From 69f7f155dd3750ff44f620556d3d46c3ae25beda Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:03:45 +0200 Subject: [PATCH 001/205] Bump version v14.3.0.1 --- CHANGELOG.md | 23 ++++++-- RELEASENOTES.md | 89 ++----------------------------- tasmota/include/tasmota_version.h | 2 +- 3 files changed, 22 insertions(+), 92 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eea973181..b1fc61941 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,24 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.2.0.6] +## [14.3.0.1] +### Added + +### Breaking Changed + +### Changed + +### Fixed + +### Removed + + +## [Released] + +## [14.3.0] 20241015 +- Release Robert + +## [14.2.0.6] 20241015 ### Added - Support for Sonoff SPM v1.3.0 (#13447) - LVGL port `colorwheel` from LVGL 8 (#22244) @@ -19,8 +36,6 @@ All notable changes to this project will be documented in this file. - Misubishi Electric HVAC prohibit function (#22269) - Misubishi Electric HVAC compressor map and operation power and energy (#22290) -### Breaking Changed - ### Changed - ESP32 platform update from 2024.09.10 to 2024.09.30 and Framework (Arduino Core) from v3.0.5 to v3.1.0.240926 (#22203) - Berry improve `persist` dirty data handling (#22246) @@ -137,8 +152,6 @@ All notable changes to this project will be documented in this file. ### Removed - ESP8266 Analog input support using energy driver as only one channel is available -## [Released] - ## [14.2.0] 20240814 - Release Rita diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5d2cb8fcc..17026f8f5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -75,7 +75,7 @@ Latest released binaries can be downloaded from - http://ota.tasmota.com/tasmota/release Historical binaries can be downloaded from -- http://ota.tasmota.com/tasmota/release-14.2.0 +- http://ota.tasmota.com/tasmota/release-14.3.0 The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` @@ -104,7 +104,7 @@ Latest released binaries can be downloaded from - https://ota.tasmota.com/tasmota32/release Historical binaries can be downloaded from -- https://ota.tasmota.com/tasmota32/release-14.2.0 +- https://ota.tasmota.com/tasmota32/release-14.3.0 The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin`` @@ -114,96 +114,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.2.0.6 +## Changelog v14.3.0.1 ### Added -- Command ``SetOption69 1`` to enable Serial Bridge inverted Receive [#22000](https://github.com/arendst/Tasmota/issues/22000) -- Command ``DaliWeb 1`` to enable light control for DALI broadcast address -- Command ``DaliSend
|,`` to send command (address+256 is repeat) on DALI bus -- Command ``DaliQuery
|,`` to send command (address+256 is repeat) on DALI bus and wait up to DALI_TIMEOUT ms for response -- HX711 optional calibration precision option on command ``Sensor34 2 `` where `` is 1 to 20 [#13983](https://github.com/arendst/Tasmota/issues/13983) -- ESP8266 support for one-wire M1601 temperature sensor on DS18x20 GPIO [#21376](https://github.com/arendst/Tasmota/issues/21376) -- ESP8266 support for I2C CLK on GPIO16 [#22199](https://github.com/arendst/Tasmota/issues/22199) -- Support for I2C M5Unit (Mini)Scales using HX711 driver -- Support for DALI on ESP8266 -- Support for RX8010 RTC as used in IOTTIMER [#21376](https://github.com/arendst/Tasmota/issues/21376) -- Support for BL0906 up to 6 channel energy monitor as used in Athom EM2/EM6 [#22167](https://github.com/arendst/Tasmota/issues/22167) -- Support for Sonoff SPM v1.3.0 [#13447](https://github.com/arendst/Tasmota/issues/13447) -- Energy command ``PowerSet 60,230`` to calibrate both Current and Power with known resistive load of 60W at 230V using calibrated Voltage -- Energy command ``CurrentSet 60,230`` to calibrate both Power and Current with known resistive load of 60W at 230V using calibrated Voltage -- ESP8266 experimental support for second I2C bus -- MQTT warning if trying to connect without TLS on a port that normally uses TLS [#22175](https://github.com/arendst/Tasmota/issues/22175) -- Energy Log level 4 message when (Calculated) Apparent Power is less than Active Power indicating wrong calibration [#20653](https://github.com/arendst/Tasmota/issues/20653) -- Support nexus protocol and calculation of separation limit to rc-switch library [#21886](https://github.com/arendst/Tasmota/issues/21886) -- KNX additional KnxTx functions and define KNX_USE_DPT9 [#22071](https://github.com/arendst/Tasmota/issues/22071) -- SML multi TRX line [#22056](https://github.com/arendst/Tasmota/issues/22056) -- Misubishi Electric HVAC Heat/Dry/Cool Auto operation mode [#22216](https://github.com/arendst/Tasmota/issues/22216) -- Misubishi Electric HVAC Bridge to HomeBridge/Homekit locally [#22236](https://github.com/arendst/Tasmota/issues/22236) -- Misubishi Electric HVAC Air Direction Control [#22241](https://github.com/arendst/Tasmota/issues/22241) -- Misubishi Electric HVAC prohibit function [#22269](https://github.com/arendst/Tasmota/issues/22269) -- Misubishi Electric HVAC compressor map and operation power and energy [#22290](https://github.com/arendst/Tasmota/issues/22290) -- Zigbee Koenkk firmware 20240710 for Sonoff Zigbee ZBPro [#22076](https://github.com/arendst/Tasmota/issues/22076) -- Berry Zigbee improvements to prepare Matter [#22083](https://github.com/arendst/Tasmota/issues/22083) -- Berry virtual Energy driver [#22134](https://github.com/arendst/Tasmota/issues/22134) -- Berry improve `int64` constructor [#22172](https://github.com/arendst/Tasmota/issues/22172) -- Berry Serial `config` to change parity on-the-fly for RS-485 [#22285](https://github.com/arendst/Tasmota/issues/22285) -- LVGL port `colorwheel` from LVGL 8 [#22244](https://github.com/arendst/Tasmota/issues/22244) -- HASPmota `cpicker` and `msgbox` [#22244](https://github.com/arendst/Tasmota/issues/22244) -- Matter support for Zigbee Temperature, Humidity and Pressure sensors [#22084](https://github.com/arendst/Tasmota/issues/22084) -- Matter support for Zigbee Occupancy and Light 0/1/2 (OnOff / Dimmer / White Color Temperature) [#22110](https://github.com/arendst/Tasmota/issues/22110) ### Breaking Changed -- Berry make `energy` modules changes from #21887 backwards compatible [#22046](https://github.com/arendst/Tasmota/issues/22046) ### Changed -- ESP8266 platform update from 2024.06.00 to 2024.09.00 and Framework (Arduino Core) from v2.7.7 to v2.7.8 [#22199](https://github.com/arendst/Tasmota/issues/22199) -- ESP32 platform update from 2024.08.10 to 2024.09.30 and Framework (Arduino Core) from v3.0.4 to v3.1.0.240926 [#22203](https://github.com/arendst/Tasmota/issues/22203) -- ESP32 LVGL library from v9.1.0 to v9.2.0 [#22031](https://github.com/arendst/Tasmota/issues/22031) -- GPIOViewer from v1.5.5 to v1.5.6 -- Add command entered to command error and command unknown message -- Refactored I2C drivers HTU21, BH1750, SHT3x, iAQ and HYT -- Energy BL09xx command ``CurrentSet`` input changed from Ampere to milliAmpere -- Command ``DaliDimmer`` range from 0..254 to 0..100 -- Energy force Apparent Power equals Active Power when (Calculated) Apparent Power is less than Active Power [#20653](https://github.com/arendst/Tasmota/issues/20653) -- Refactor and fix PID sensor (PID_USE_LOCAL_SENSOR) read race condition [#22162](https://github.com/arendst/Tasmota/issues/22162) -- SCD30 Lowered I2C clock from 100k to 50k [#15438](https://github.com/arendst/Tasmota/issues/15438) -- HASPmota `delete` instead of `delete()` [#22245](https://github.com/arendst/Tasmota/issues/22245) ### Fixed -- DALI received data decoding -- Compilation exception when metrics not found [#22170](https://github.com/arendst/Tasmota/issues/22170) -- Crash when calling TasmotaSerial destructor when initialized with incorrect arguments [#22036](https://github.com/arendst/Tasmota/issues/22036) -- Energy calculation [#20653](https://github.com/arendst/Tasmota/issues/20653) -- SML trx pin error [#22119](https://github.com/arendst/Tasmota/issues/22119) -- Shutter timing registers overflow [#21966](https://github.com/arendst/Tasmota/issues/21966) -- Shutter missing HOLD on shutterbutton [#22108](https://github.com/arendst/Tasmota/issues/22108) -- Shutter remaining issues on shutterinvert [#22120](https://github.com/arendst/Tasmota/issues/22120) -- PZEM continue energy monitoring when one phase fails [#21968](https://github.com/arendst/Tasmota/issues/21968) -- BearSSL panic on ESP8266 in rare conditions [#22017](https://github.com/arendst/Tasmota/issues/22017) -- ModbusBridge request and response logic [#22075](https://github.com/arendst/Tasmota/issues/22075) -- Sonoff WTS01 temperature sensor shows incorrect negative temperature [#19373](https://github.com/arendst/Tasmota/issues/19373) -- Autoconf prevent 'init.bat' from stopping on empty lines [#22158](https://github.com/arendst/Tasmota/issues/22158) -- Zigbee extend timeout for MCU reboot from 5s to 10s [#22009](https://github.com/arendst/Tasmota/issues/22009) -- Zigbee avoid disabling console serial on ESP32 and improved log messages [#22082](https://github.com/arendst/Tasmota/issues/22082) -- Zigbee flashing CC2562P with latest firmware [#22117](https://github.com/arendst/Tasmota/issues/22117) -- ESP32 Range Extender compile error with core 3.x [#22205](https://github.com/arendst/Tasmota/issues/22205) -- ESP32 DALI compile error with core 3.x [#22214](https://github.com/arendst/Tasmota/issues/22214) -- ESP32 Ethernet using EthClockMode 3 [#22248](https://github.com/arendst/Tasmota/issues/22248) -- ESP32 disable SPI DMA for uDisplay (broken since esp-idf 5.3 (core 3.1.0)) [#22264](https://github.com/arendst/Tasmota/issues/22264) -- Berry avoid `readbytes()` from crashing when file is too large [#22057](https://github.com/arendst/Tasmota/issues/22057) -- Berry energy missing attributes [#22116](https://github.com/arendst/Tasmota/issues/22116) -- Berry I2C to prepare M5Stack I2C STM32 based devices [#22143](https://github.com/arendst/Tasmota/issues/22143) -- Berry improve `persist` dirty data handling [#22246](https://github.com/arendst/Tasmota/issues/22246) -- ESP32-S3 uDisplay force cache writes to RGB display [#22222](https://github.com/arendst/Tasmota/issues/22222) -- LVGL Added OpenHASP icons to font `montserrat-28` [#22048](https://github.com/arendst/Tasmota/issues/22048) -- LVGL compilation of lv_menu [#22188](https://github.com/arendst/Tasmota/issues/22188) -- HASPmota broken `changed` event [#22194](https://github.com/arendst/Tasmota/issues/22194) -- HASPmota error when page '1' is not defined [#22220](https://github.com/arendst/Tasmota/issues/22220) -- Matter fixed UI bug when no endpoints configured [#22008](https://github.com/arendst/Tasmota/issues/22008) -- Matter fix when Rules are disabled [#22016](https://github.com/arendst/Tasmota/issues/22016) -- Matter fail to report Shutter status if no shutter is configured in Tasmota [#22049](https://github.com/arendst/Tasmota/issues/22049) -- Matter fix Waterleak broken after Berry solidification optimisation #21885 [#22052](https://github.com/arendst/Tasmota/issues/22052) ### Removed -- ESP8266 Analog input support using energy driver as only one channel is available -- Berry remove reuse of methods for interface-like code reuse #21500 [#22055](https://github.com/arendst/Tasmota/issues/22055) -- Berry Zigbee removed test code [#22263](https://github.com/arendst/Tasmota/issues/22263) diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 54b598557..152e8fb7d 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E020006; // 14.2.0.6 +const uint32_t TASMOTA_VERSION = 0x0E030001; // 14.3.0.1 #endif // _TASMOTA_VERSION_H_ From aed98a6b64ae0c45eedf5730975b2cc9a34ac4f0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:24:29 +0200 Subject: [PATCH 002/205] Platform 2024.10.30 (Arduino core 3.1.0.241015 / IDF 5.3.1+) (#22299) * Platform 2024.10.30 (Arduino core 3.1.0.241015 / IDF 5.3.1+) Platform new option custom Arduino IDF libs * Tasmota core ESP32 V.3.1.0.241015 --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- platformio_tasmota32.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0b3b15674..e8df939fe 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.8 - - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.240926 + - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241015 - [ ] 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/platformio_tasmota32.ini b/platformio_tasmota32.ini index df2702f0c..d35eece2f 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -82,7 +82,7 @@ lib_ignore = ${esp32_defaults.lib_ignore} ccronexpr [core32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.09.30/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.10.30/platform-espressif32.zip platform_packages = build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} From 0f84211898fd7c5bd0988ae51bc3bab90fb15dfb Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:55:15 +0200 Subject: [PATCH 003/205] remove LTO settings in build flags (#22302) since LTO is now standard in Tasmota Arduino framework --- platformio_tasmota32.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index d35eece2f..15b19d401 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -8,7 +8,6 @@ build_unflags = ${esp_defaults.build_unflags} -Wincompatible-pointer-types -Wnonnull-compare -fexceptions - -fno-lto -Wpointer-arith build_flags = ${esp_defaults.build_flags} ; comment next line to disable IPv6 support @@ -17,7 +16,6 @@ build_flags = ${esp_defaults.build_flags} -Wno-switch-unreachable -Wno-stringop-overflow -fno-exceptions - -flto=auto -DBUFFER_LENGTH=128 -DHTTP_UPLOAD_BUFLEN=2048 -DMQTT_MAX_PACKET_SIZE=1200 From e39f1cc83f17100adc41fb8b6d18a792ecd50c11 Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Wed, 16 Oct 2024 18:14:00 +0200 Subject: [PATCH 004/205] track BLE devices with RPA (#22300) --- .../esp-nimble-cpp/CMakeLists.txt | 2 + lib/libesp32_div/esp-nimble-cpp/Kconfig | 13 +- .../docs/Improvements_and_updates.md | 2 +- .../esp-nimble-cpp/docs/Migration_guide.md | 19 +- .../Advanced/NimBLE_Client/main/main.cpp | 30 +-- .../Advanced/NimBLE_Server/main/main.cpp | 14 +- .../NimBLE_extended_client/main/main.cpp | 2 +- .../NimBLE_active_passive_scan.ino | 48 ---- .../CMakeLists.txt | 7 + .../main/CMakeLists.txt | 4 + .../main/main.cpp | 83 +++++++ .../examples/basic/BLE_client/main/main.cpp | 31 ++- .../examples/basic/BLE_notify/main/main.cpp | 33 ++- .../examples/basic/BLE_uart/main/main.cpp | 32 ++- lib/libesp32_div/esp-nimble-cpp/package.json | 17 ++ .../esp-nimble-cpp/src/NimBLE2904.cpp | 4 - .../esp-nimble-cpp/src/NimBLE2904.h | 3 - .../esp-nimble-cpp/src/NimBLEAddress.cpp | 9 + .../esp-nimble-cpp/src/NimBLEAddress.h | 1 + .../src/NimBLEAdvertisedDevice.cpp | 26 ++ .../src/NimBLEAdvertisedDevice.h | 2 + .../esp-nimble-cpp/src/NimBLEAdvertising.cpp | 57 +++-- .../esp-nimble-cpp/src/NimBLEAdvertising.h | 10 +- .../esp-nimble-cpp/src/NimBLEAttValue.h | 13 +- .../src/NimBLECharacteristic.cpp | 14 +- .../esp-nimble-cpp/src/NimBLEClient.cpp | 135 ++++++++--- .../esp-nimble-cpp/src/NimBLEClient.h | 19 +- .../esp-nimble-cpp/src/NimBLEConnInfo.h | 34 +-- .../esp-nimble-cpp/src/NimBLEDescriptor.cpp | 19 +- .../esp-nimble-cpp/src/NimBLEDevice.cpp | 97 ++++++-- .../esp-nimble-cpp/src/NimBLEDevice.h | 4 +- .../esp-nimble-cpp/src/NimBLEEddystoneTLM.cpp | 4 +- .../src/NimBLEExtAdvertising.cpp | 5 +- .../esp-nimble-cpp/src/NimBLEHIDDevice.cpp | 77 +++--- .../esp-nimble-cpp/src/NimBLEHIDDevice.h | 1 + .../esp-nimble-cpp/src/NimBLELog.h | 22 +- .../esp-nimble-cpp/src/NimBLEScan.cpp | 4 +- .../esp-nimble-cpp/src/NimBLEServer.cpp | 223 +++++++++++++++--- .../esp-nimble-cpp/src/NimBLEServer.h | 50 +++- .../esp-nimble-cpp/src/NimBLEService.cpp | 14 +- .../esp-nimble-cpp/src/NimBLEService.h | 2 +- .../esp-nimble-cpp/src/NimBLEUtils.cpp | 39 --- .../esp-nimble-cpp/src/NimBLEUtils.h | 1 - .../esp-nimble-cpp/src/nimconfig.h | 12 + tasmota/include/xsns_62_esp32_mi.h | 7 +- .../xdrv_52_3_berry_MI32.ino | 86 +++++-- .../tasmota_xsns_sensor/xsns_62_esp32_mi.ino | 63 ++++- 47 files changed, 987 insertions(+), 407 deletions(-) create mode 100644 lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/CMakeLists.txt create mode 100644 lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/main/CMakeLists.txt create mode 100644 lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/main/main.cpp create mode 100644 lib/libesp32_div/esp-nimble-cpp/package.json diff --git a/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt b/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt index 90c22bd19..4bed65b11 100644 --- a/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt +++ b/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt @@ -31,6 +31,7 @@ idf_component_register( "esp32c2" "esp32c3" "esp32c6" + "esp32h2" INCLUDE_DIRS "src" SRCS @@ -58,6 +59,7 @@ idf_component_register( REQUIRES bt nvs_flash + driver PRIV_REQUIRES ${ESP_NIMBLE_PRIV_REQUIRES} ) diff --git a/lib/libesp32_div/esp-nimble-cpp/Kconfig b/lib/libesp32_div/esp-nimble-cpp/Kconfig index 730f8cd96..0878176a8 100644 --- a/lib/libesp32_div/esp-nimble-cpp/Kconfig +++ b/lib/libesp32_div/esp-nimble-cpp/Kconfig @@ -33,7 +33,7 @@ config NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT Enabling this option will display return code values as text messages in the debug log. This will use approximately 8kB of flash memory. - + config NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT bool "Show NimBLE gap events as text in debug log." default "n" @@ -47,7 +47,7 @@ config NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT default "n" help Enabling this option will display advertisment types recieved - while scanning as text messages in the debug log. + while scanning as text messages in the debug log. This will use approximately 250 bytes of flash memory. config NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED @@ -68,5 +68,12 @@ config NIMBLE_CPP_ATT_VALUE_INIT_LENGTH when the constructor is called. This is also the size used when a remote characteristic or descriptor is constructed before a value is read/notifed. Increasing this will reduce reallocations but increase memory footprint. - + +config NIMBLE_CPP_DEBUG_ASSERT_ENABLED + bool "Enable debug asserts." + default "n" + help + Enabling this option will add debug asserts to the NimBLE CPP library. + This will use approximately 1kB of flash memory. + endmenu diff --git a/lib/libesp32_div/esp-nimble-cpp/docs/Improvements_and_updates.md b/lib/libesp32_div/esp-nimble-cpp/docs/Improvements_and_updates.md index 220ed5c28..a7504d5fb 100644 --- a/lib/libesp32_div/esp-nimble-cpp/docs/Improvements_and_updates.md +++ b/lib/libesp32_div/esp-nimble-cpp/docs/Improvements_and_updates.md @@ -66,7 +66,7 @@ If false the service is only removed from visibility by clients. The pointers to # Advertising `NimBLEAdvertising::start` -Now takes 2 optional parameters, the first is the duration to advertise for (in seconds), the second is a callback that is invoked when advertising ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API). +Now takes 2 optional parameters, the first is the duration to advertise for (in milliseconds), the second is a callback that is invoked when advertising ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API). This provides an opportunity to update the advertisement data if desired. diff --git a/lib/libesp32_div/esp-nimble-cpp/docs/Migration_guide.md b/lib/libesp32_div/esp-nimble-cpp/docs/Migration_guide.md index d6362e2b2..d1fcee8ad 100644 --- a/lib/libesp32_div/esp-nimble-cpp/docs/Migration_guide.md +++ b/lib/libesp32_div/esp-nimble-cpp/docs/Migration_guide.md @@ -255,7 +255,7 @@ Calling `NimBLEAdvertising::setAdvertisementData` will entirely replace any data > BLEAdvertising::start (NimBLEAdvertising::start) -Now takes 2 optional parameters, the first is the duration to advertise for (in seconds), the second is a callback that is invoked when advertising ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API). +Now takes 2 optional parameters, the first is the duration to advertise for (in milliseconds), the second is a callback that is invoked when advertising ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API). This provides an opportunity to update the advertisement data if desired.
@@ -383,18 +383,23 @@ The security callback methods are now incorporated in the `NimBLEServerCallbacks The callback methods are: -> `bool onConfirmPIN(uint32_t pin)` +> `bool onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin)` -Receives the pin when using numeric comparison authentication, `return true;` to accept. +Receives the pin when using numeric comparison authentication. +Call `NimBLEDevice::injectConfirmPIN(connInfo, true);` to accept or `NimBLEDevice::injectConfirmPIN(connInfo, false);` to reject.
-> `uint32_t onPassKeyRequest()` +> `void onPassKeyEntry(const NimBLEConnInfo& connInfo)` -For server callback; return the passkey expected from the client. -For client callback; return the passkey to send to the server. +Client callback; client should respond with the passkey (pin) by calling `NimBLEDevice::injectPassKey(connInfo, 123456);`
-> `void onAuthenticationComplete(NimBLEConnInfo& connInfo)` +> `uint32_t onPassKeyDisplay()` + +Server callback; should return the passkey (pin) expected from the client. +
+ +> `void onAuthenticationComplete(const NimBLEConnInfo& connInfo)` Authentication complete, success or failed information is available from the `NimBLEConnInfo` methods.
diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/Advanced/NimBLE_Client/main/main.cpp b/lib/libesp32_div/esp-nimble-cpp/examples/Advanced/NimBLE_Client/main/main.cpp index e30bd646b..fe76dd0d9 100644 --- a/lib/libesp32_div/esp-nimble-cpp/examples/Advanced/NimBLE_Client/main/main.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/examples/Advanced/NimBLE_Client/main/main.cpp @@ -39,20 +39,22 @@ class ClientCallbacks : public NimBLEClientCallbacks { /********************* Security handled here ********************** ****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyRequest(){ - printf("Client Passkey Request\n"); - /** return the passkey to send to the server */ - return 123456; - } + void onPassKeyEntry(const NimBLEConnInfo& connInfo){ + printf("Server Passkey Entry\n"); + /** This should prompt the user to enter the passkey displayed + * on the peer device. + */ + NimBLEDevice::injectPassKey(connInfo, 123456); + }; - bool onConfirmPIN(uint32_t pass_key){ - printf("The passkey YES/NO number: %" PRIu32"\n", pass_key); - /** Return false if passkeys don't match. */ - return true; - } + void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pass_key){ + printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); + /** Inject false if passkeys don't match. */ + NimBLEDevice::injectConfirmPIN(connInfo, true); + }; /** Pairing process complete, we can check the results in connInfo */ - void onAuthenticationComplete(NimBLEConnInfo& connInfo){ + void onAuthenticationComplete(const NimBLEConnInfo& connInfo){ if(!connInfo.isEncrypted()) { printf("Encrypt connection failed - disconnecting\n"); /** Find the client with the connection handle provided in desc */ @@ -146,8 +148,8 @@ bool connectToServer() { * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 12 * 10ms = 120ms timeout */ pClient->setConnectionParams(6,6,0,15); - /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ - pClient->setConnectTimeout(5); + /** Set how long we are willing to wait for the connection to complete (milliseconds), default is 30000. */ + pClient->setConnectTimeout(5 * 1000); if (!pClient->connect(advDevice)) { @@ -358,7 +360,7 @@ void app_main (void){ * but will use more energy from both devices */ pScan->setActiveScan(true); - /** Start scanning for advertisers for the scan time specified (in seconds) 0 = forever + /** Start scanning for advertisers for the scan time specified (in milliseconds) 0 = forever * Optional callback for when scanning stops. */ pScan->start(scanTime); diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/Advanced/NimBLE_Server/main/main.cpp b/lib/libesp32_div/esp-nimble-cpp/examples/Advanced/NimBLE_Server/main/main.cpp index 8bf92e26a..3effb54f2 100644 --- a/lib/libesp32_div/esp-nimble-cpp/examples/Advanced/NimBLE_Server/main/main.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/examples/Advanced/NimBLE_Server/main/main.cpp @@ -44,21 +44,21 @@ class ServerCallbacks: public NimBLEServerCallbacks { /********************* Security handled here ********************** ****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyRequest(){ - printf("Server Passkey Request\n"); + uint32_t onPassKeyDisplay(){ + printf("Server Passkey Display\n"); /** This should return a random 6 digit number for security * or make your own static passkey as done here. */ return 123456; }; - bool onConfirmPIN(uint32_t pass_key){ - printf("The passkey YES/NO number: %" PRIu32"\n", pass_key); - /** Return false if passkeys don't match. */ - return true; + void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pass_key){ + printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); + /** Inject false if passkeys don't match. */ + NimBLEDevice::injectConfirmPIN(connInfo, true); }; - void onAuthenticationComplete(NimBLEConnInfo& connInfo){ + void onAuthenticationComplete(const NimBLEConnInfo& connInfo){ /** Check that encryption was successful, if not we disconnect the client */ if(!connInfo.isEncrypted()) { NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle()); diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/Bluetooth_5/NimBLE_extended_client/main/main.cpp b/lib/libesp32_div/esp-nimble-cpp/examples/Bluetooth_5/NimBLE_extended_client/main/main.cpp index c9013d9c7..3572e59ef 100644 --- a/lib/libesp32_div/esp-nimble-cpp/examples/Bluetooth_5/NimBLE_extended_client/main/main.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/examples/Bluetooth_5/NimBLE_extended_client/main/main.cpp @@ -154,7 +154,7 @@ void app_main (void) { */ pScan->setActiveScan(true); - /* Start scanning for advertisers for the scan time specified (in seconds) 0 = forever + /* Start scanning for advertisers for the scan time specified (in milliseconds) 0 = forever * Optional callback for when scanning stops. */ pScan->start(scanTime); diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino b/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino index 9dceb4e67..e69de29bb 100644 --- a/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino +++ b/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino @@ -1,48 +0,0 @@ -/* - * NimBLE Scan active/passive switching demo - * - * Demonstrates the use of the scan callbacks while alternating between passive and active scanning. - */ - -#include "NimBLEDevice.h" -int scanTime = 5 * 1000; // In milliseconds, 0 = scan forever -BLEScan* pBLEScan; - -bool active = false; - -class scanCallbacks: public NimBLEScanCallbacks { - - void onDiscovered(NimBLEAdvertisedDevice* advertisedDevice) { - Serial.printf("Discovered Advertised Device: %s \n", advertisedDevice->toString().c_str()); - } - - void onResult(NimBLEAdvertisedDevice* advertisedDevice) { - Serial.printf("Advertised Device Result: %s \n", advertisedDevice->toString().c_str()); - } - - void onScanEnd(NimBLEScanResults results){ - Serial.println("Scan Ended"); - active = !active; - pBLEScan->setActiveScan(active); - Serial.printf("scan start, active = %u\n", active); - pBLEScan->start(scanTime); - } -}; - - - -void setup() { - Serial.begin(115200); - Serial.println("Scanning..."); - - NimBLEDevice::init(""); - pBLEScan = NimBLEDevice::getScan(); - pBLEScan->setScanCallbacks(new scanCallbacks()); - pBLEScan->setActiveScan(active); - pBLEScan->setInterval(100); - pBLEScan->setWindow(99); - pBLEScan->start(scanTime); -} - -void loop() { -} diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/CMakeLists.txt b/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/CMakeLists.txt new file mode 100644 index 000000000..21c12dad3 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/CMakeLists.txt @@ -0,0 +1,7 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(SUPPORTED_TARGETS esp32) +project(NimBLE_server_get_client_name) diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/main/CMakeLists.txt b/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/main/CMakeLists.txt new file mode 100644 index 000000000..0a5a557ec --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_SRCS "main.cpp") +set(COMPONENT_ADD_INCLUDEDIRS ".") + +register_component() diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/main/main.cpp b/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/main/main.cpp new file mode 100644 index 000000000..e255807f8 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/examples/NimBLE_server_get_client_name/main/main.cpp @@ -0,0 +1,83 @@ +/** NimBLE_server_get_client_name + * + * Demonstrates 2 ways for the server to read the device name from the connected client. + * + * Created: on June 24 2024 + * Author: H2zero + * + */ + +#include + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ + +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" +#define ENC_CHARACTERISTIC_UUID "9551f35b-8d91-42e4-8f7e-1358dfe272dc" + +NimBLEServer* pServer; + +class ServerCallbacks : public NimBLEServerCallbacks { + // Same as before but now includes the name parameter + void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, std::string& name) override { + printf("Client address: %s Name: %s\n", connInfo.getAddress().toString().c_str(), name.c_str()); + } + + // Same as before but now includes the name parameter + void onAuthenticationComplete(const NimBLEConnInfo& connInfo, const std::string& name) override { + if (!connInfo.isEncrypted()) { + NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle()); + printf("Encrypt connection failed - disconnecting client\n"); + return; + } + + printf("Encrypted Client address: %s Name: %s\n", connInfo.getAddress().toString().c_str(), name.c_str()); + } +}; + +extern "C" void app_main(void) { + printf("Starting BLE Server!\n"); + + NimBLEDevice::init("Connect to me!"); + NimBLEDevice::setSecurityAuth(true, false, true); // Enable bonding to see full name on phones. + + pServer = NimBLEDevice::createServer(); + NimBLEService* pService = pServer->createService(SERVICE_UUID); + NimBLECharacteristic* pCharacteristic = + pService->createCharacteristic(CHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE); + pCharacteristic->setValue("Hello World says NimBLE!"); + + NimBLECharacteristic* pEncCharacteristic = pService->createCharacteristic( + ENC_CHARACTERISTIC_UUID, + (NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC)); + pEncCharacteristic->setValue("Hello World says NimBLE Encrypted"); + + pService->start(); + + pServer->setCallbacks(new ServerCallbacks()); + pServer->getPeerNameOnConnect(true); // Setting this will enable the onConnect callback that provides the name. + + BLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(true); + + pAdvertising->start(); + printf("Advertising started, connect with your phone.\n"); + + while (true) { + auto clientCount = pServer->getConnectedCount(); + if (clientCount) { + printf("Connected clients:\n"); + for (auto i = 0; i < clientCount; ++i) { + NimBLEConnInfo peerInfo = pServer->getPeerInfo(i); + printf("Client address: %s Name: %s\n", peerInfo.getAddress().toString().c_str(), + // This function blocks until the name is retrieved, so cannot be used in callback functions. + pServer->getPeerName(peerInfo).c_str()); + + } + } + + vTaskDelay(pdMS_TO_TICKS(10000)); + } +} diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_client/main/main.cpp b/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_client/main/main.cpp index 18308840e..cfb80e9bf 100644 --- a/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_client/main/main.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_client/main/main.cpp @@ -51,17 +51,28 @@ class MyClientCallback : public BLEClientCallbacks { } /***************** New - Security handled here ******************** ****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyRequest(){ - printf("Client PassKeyRequest\n"); - return 123456; - } - bool onConfirmPIN(uint32_t pass_key){ - printf("The passkey YES/NO number: %" PRIu32"\n", pass_key); - return true; - } + void onPassKeyEntry(const NimBLEConnInfo& connInfo){ + printf("Server Passkey Entry\n"); + /** This should prompt the user to enter the passkey displayed + * on the peer device. + */ + NimBLEDevice::injectPassKey(connInfo, 123456); + }; - void onAuthenticationComplete(BLEConnInfo& connInfo){ - printf("Starting BLE work!\n"); + void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pass_key){ + printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); + /** Inject false if passkeys don't match. */ + NimBLEDevice::injectConfirmPIN(connInfo, true); + }; + + /** Pairing process complete, we can check the results in connInfo */ + void onAuthenticationComplete(const NimBLEConnInfo& connInfo){ + if(!connInfo.isEncrypted()) { + printf("Encrypt connection failed - disconnecting\n"); + /** Find the client with the connection handle provided in desc */ + NimBLEDevice::getClientByID(connInfo.getConnHandle())->disconnect(); + return; + } } /*******************************************************************/ }; diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_notify/main/main.cpp b/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_notify/main/main.cpp index e966f8b8e..b17f49aaa 100644 --- a/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_notify/main/main.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_notify/main/main.cpp @@ -57,19 +57,29 @@ class MyServerCallbacks: public BLEServerCallbacks { } /***************** New - Security handled here ******************** ****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyRequest(){ - printf("Server PassKeyRequest\n"); - return 123456; - } + uint32_t onPassKeyDisplay(){ + printf("Server Passkey Display\n"); + /** This should return a random 6 digit number for security + * or make your own static passkey as done here. + */ + return 123456; + }; - bool onConfirmPIN(uint32_t pass_key){ - printf("The passkey YES/NO number: %" PRIu32"\n", pass_key); - return true; - } + void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pass_key){ + printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); + /** Inject false if passkeys don't match. */ + NimBLEDevice::injectConfirmPIN(connInfo, true); + }; - void onAuthenticationComplete(BLEConnInfo& connInfo){ - printf("Starting BLE work!\n"); - } + void onAuthenticationComplete(const NimBLEConnInfo& connInfo){ + /** Check that encryption was successful, if not we disconnect the client */ + if(!connInfo.isEncrypted()) { + NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle()); + printf("Encrypt connection failed - disconnecting client\n"); + return; + } + printf("Starting BLE work!"); + }; /*******************************************************************/ }; @@ -128,7 +138,6 @@ void app_main(void) { NIMBLE_PROPERTY::INDICATE ); - // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml // Create a BLE Descriptor /*************************************************** NOTE: DO NOT create a 2902 descriptor. diff --git a/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_uart/main/main.cpp b/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_uart/main/main.cpp index 3aa20fb94..18df6fa63 100644 --- a/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_uart/main/main.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/examples/basic/BLE_uart/main/main.cpp @@ -59,19 +59,29 @@ class MyServerCallbacks: public BLEServerCallbacks { } /***************** New - Security handled here ******************** ****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyRequest(){ - printf("Server PassKeyRequest\n"); - return 123456; - } + uint32_t onPassKeyDisplay(){ + printf("Server Passkey Display\n"); + /** This should return a random 6 digit number for security + * or make your own static passkey as done here. + */ + return 123456; + }; - bool onConfirmPIN(uint32_t pass_key){ - printf("The passkey YES/NO number: %" PRIu32"\n", pass_key); - return true; - } + void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pass_key){ + printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); + /** Inject false if passkeys don't match. */ + NimBLEDevice::injectConfirmPIN(connInfo, true); + }; - void onAuthenticationComplete(BLEConnInfo& connInfo){ - printf("Starting BLE work!\n"); - } + void onAuthenticationComplete(const NimBLEConnInfo& connInfo){ + /** Check that encryption was successful, if not we disconnect the client */ + if(!connInfo.isEncrypted()) { + NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle()); + printf("Encrypt connection failed - disconnecting client\n"); + return; + } + printf("Starting BLE work!"); + }; /*******************************************************************/ }; diff --git a/lib/libesp32_div/esp-nimble-cpp/package.json b/lib/libesp32_div/esp-nimble-cpp/package.json new file mode 100644 index 000000000..1efe13e63 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/package.json @@ -0,0 +1,17 @@ +{ + "name": "esp-nimble-cpp", + "version": "1.5.0", + "description": "NimBLE, BLE stack for the Espressif ESP32, ESP32-S and ESP32-C series of SoCs", + "keywords": [ + "BLE", + "espidf", + "arduino", + "espressif", + "esp32" + ], + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://github.com/h2zero/esp-nimble-cpp" + } +} diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLE2904.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLE2904.cpp index b518d9b00..486fa5ef5 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLE2904.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLE2904.cpp @@ -12,10 +12,6 @@ * Author: kolban */ -/* - * See also: - * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml - */ #include "nimconfig.h" #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLE2904.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLE2904.h index 29dde51e8..52ae2d3db 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLE2904.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLE2904.h @@ -33,9 +33,6 @@ struct BLE2904_Data { * @brief Descriptor for Characteristic Presentation Format. * * This is a convenience descriptor for the Characteristic Presentation Format which has a UUID of 0x2904. - * - * See also: - * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml */ class NimBLE2904: public NimBLEDescriptor { public: diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAddress.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAddress.cpp index d8ce5e88c..af7956b3c 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAddress.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAddress.cpp @@ -138,6 +138,15 @@ uint8_t NimBLEAddress::getType() const { } // getType +/** + * @brief Determine if this address is a Resolvable Private Address. + * @return True if the address is a RPA. + */ +bool NimBLEAddress::isRpa() const { + return (m_addrType && ((m_address[5] & 0xc0) == 0x40)); +} // isRpa + + /** * @brief Convert a BLE address to a string. * diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAddress.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAddress.h index a6e10a09c..8a55b3ebf 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAddress.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAddress.h @@ -43,6 +43,7 @@ public: NimBLEAddress(uint8_t address[6], uint8_t type = BLE_ADDR_PUBLIC); NimBLEAddress(const std::string &stringAddress, uint8_t type = BLE_ADDR_PUBLIC); NimBLEAddress(const uint64_t &address, uint8_t type = BLE_ADDR_PUBLIC); + bool isRpa() const; bool equals(const NimBLEAddress &otherAddress) const; const uint8_t* getNative() const; std::string toString() const; diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertisedDevice.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertisedDevice.cpp index 3ef71f541..bdc1358eb 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertisedDevice.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertisedDevice.cpp @@ -203,6 +203,24 @@ std::string NimBLEAdvertisedDevice::getURI() { return ""; } // getURI +/** + * @brief Get the data from any type available in the advertisement + * @param [in] type The advertised data type BLE_HS_ADV_TYPE + * @return The data available under the type `type` +*/ +std::string NimBLEAdvertisedDevice::getPayloadByType(uint16_t type) { + size_t data_loc = 0; + + if(findAdvField(type, 0, &data_loc) > 0) { + ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc]; + if(field->length > 1) { + return std::string((char*)field->value, field->length - 1); + } + } + + return ""; +} // getPayloadByType + /** * @brief Get the advertised name. @@ -556,6 +574,14 @@ bool NimBLEAdvertisedDevice::haveURI() { return findAdvField(BLE_HS_ADV_TYPE_URI) > 0; } // haveURI +/** + * @brief Does this advertisement have a adv type `type`? + * @return True if there is a `type` present. +*/ +bool NimBLEAdvertisedDevice::haveType(uint16_t type) { + return findAdvField(type) > 0; +} + /** * @brief Does the advertisement contain a target address? diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertisedDevice.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertisedDevice.h index 5b7a69f24..7869fb547 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertisedDevice.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertisedDevice.h @@ -53,6 +53,7 @@ public: uint8_t getManufacturerDataCount(); std::string getManufacturerData(uint8_t index = 0); std::string getURI(); + std::string getPayloadByType(uint16_t type); /** * @brief A template to convert the service data to . @@ -134,6 +135,7 @@ public: bool haveAdvInterval(); bool haveTargetAddress(); bool haveURI(); + bool haveType(uint16_t type); std::string toString(); bool isConnectable(); bool isLegacyAdvertisement(); diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertising.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertising.cpp index 283f26493..0ce08ed58 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertising.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertising.cpp @@ -96,8 +96,8 @@ void NimBLEAdvertising::addServiceUUID(const char* serviceUUID) { /** - * @brief Add a service uuid to exposed list of services. - * @param [in] serviceUUID The UUID of the service to expose. + * @brief Remove a service UUID from the advertisment. + * @param [in] serviceUUID The UUID of the service to remove. */ void NimBLEAdvertising::removeServiceUUID(const NimBLEUUID &serviceUUID) { for(auto it = m_serviceUUIDs.begin(); it != m_serviceUUIDs.end(); ++it) { @@ -110,10 +110,17 @@ void NimBLEAdvertising::removeServiceUUID(const NimBLEUUID &serviceUUID) { } // addServiceUUID +/** + * @brief Remove all service UUIDs from the advertisment. + */ +void NimBLEAdvertising::removeServices() { + std::vector().swap(m_serviceUUIDs); + m_advDataSet = false; +} // removeServices + + /** * @brief Set the device appearance in the advertising data. - * The codes for distinct appearances can be found here:\n - * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml. * @param [in] appearance The appearance of the device in the advertising data. */ void NimBLEAdvertising::setAppearance(uint16_t appearance) { @@ -137,7 +144,7 @@ void NimBLEAdvertising::addTxPower() { * @param [in] name The name to advertise. */ void NimBLEAdvertising::setName(const std::string &name) { - m_name.assign(name.begin(), name.end()); + std::vector(name.begin(), name.end()).swap(m_name); m_advData.name = &m_name[0]; m_advData.name_len = m_name.size(); m_advDataSet = false; @@ -149,7 +156,7 @@ void NimBLEAdvertising::setName(const std::string &name) { * @param [in] data The data to advertise. */ void NimBLEAdvertising::setManufacturerData(const std::string &data) { - m_mfgData.assign(data.begin(), data.end()); + std::vector(data.begin(), data.end()).swap(m_mfgData); m_advData.mfg_data = &m_mfgData[0]; m_advData.mfg_data_len = m_mfgData.size(); m_advDataSet = false; @@ -173,7 +180,7 @@ void NimBLEAdvertising::setManufacturerData(const std::vector &data) { * @param [in] uri The URI to advertise. */ void NimBLEAdvertising::setURI(const std::string &uri) { - m_uri.assign(uri.begin(), uri.end()); + std::vector(uri.begin(), uri.end()).swap(m_uri); m_advData.uri = &m_uri[0]; m_advData.uri_len = m_uri.size(); m_advDataSet = false; @@ -189,7 +196,8 @@ void NimBLEAdvertising::setURI(const std::string &uri) { void NimBLEAdvertising::setServiceData(const NimBLEUUID &uuid, const std::string &data) { switch (uuid.bitSize()) { case 16: { - m_svcData16.assign((uint8_t*)&uuid.getNative()->u16.value, (uint8_t*)&uuid.getNative()->u16.value + 2); + std::vector((uint8_t*)&uuid.getNative()->u16.value, + (uint8_t*)&uuid.getNative()->u16.value + 2).swap(m_svcData16); m_svcData16.insert(m_svcData16.end(), data.begin(), data.end()); m_advData.svc_data_uuid16 = (uint8_t*)&m_svcData16[0]; m_advData.svc_data_uuid16_len = (data.length() > 0) ? m_svcData16.size() : 0; @@ -197,7 +205,8 @@ void NimBLEAdvertising::setServiceData(const NimBLEUUID &uuid, const std::string } case 32: { - m_svcData32.assign((uint8_t*)&uuid.getNative()->u32.value, (uint8_t*)&uuid.getNative()->u32.value + 4); + std::vector((uint8_t*)&uuid.getNative()->u32.value, + (uint8_t*)&uuid.getNative()->u32.value + 4).swap(m_svcData32); m_svcData32.insert(m_svcData32.end(), data.begin(), data.end()); m_advData.svc_data_uuid32 = (uint8_t*)&m_svcData32[0]; m_advData.svc_data_uuid32_len = (data.length() > 0) ? m_svcData32.size() : 0; @@ -205,7 +214,8 @@ void NimBLEAdvertising::setServiceData(const NimBLEUUID &uuid, const std::string } case 128: { - m_svcData128.assign(uuid.getNative()->u128.value, uuid.getNative()->u128.value + 16); + std::vector(uuid.getNative()->u128.value, + uuid.getNative()->u128.value + 16).swap(m_svcData128); m_svcData128.insert(m_svcData128.end(), data.begin(), data.end()); m_advData.svc_data_uuid128 = (uint8_t*)&m_svcData128[0]; m_advData.svc_data_uuid128_len = (data.length() > 0) ? m_svcData128.size() : 0; @@ -402,7 +412,7 @@ void NimBLEAdvertising::setScanResponseData(NimBLEAdvertisementData& advertiseme * @param [in] dirAddr The address of a peer to directly advertise to. * @return True if advertising started successfully. */ -bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdvertising *pAdv), NimBLEAddress* dirAddr) { +bool NimBLEAdvertising::start(uint32_t duration, advCompleteCB_t advCompleteCB, NimBLEAddress* dirAddr) { NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData); @@ -490,8 +500,8 @@ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdv if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc((void*)m_advData.uuids16, (m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t)))) { - NIMBLE_LOGC(LOG_TAG, "Error, no mem"); - abort(); + NIMBLE_LOGE(LOG_TAG, "Error, no mem"); + return false; } memcpy((void*)&m_advData.uuids16[m_advData.num_uuids16], &it.getNative()->u16, sizeof(ble_uuid16_t)); @@ -509,8 +519,8 @@ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdv if(nullptr == (m_advData.uuids32 = (ble_uuid32_t*)realloc((void*)m_advData.uuids32, (m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t)))) { - NIMBLE_LOGC(LOG_TAG, "Error, no mem"); - abort(); + NIMBLE_LOGE(LOG_TAG, "Error, no mem"); + return false; } memcpy((void*)&m_advData.uuids32[m_advData.num_uuids32], &it.getNative()->u32, sizeof(ble_uuid32_t)); @@ -528,8 +538,8 @@ bool NimBLEAdvertising::start(uint32_t duration, void (*advCompleteCB)(NimBLEAdv if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc((void*)m_advData.uuids128, (m_advData.num_uuids128 + 1) * sizeof(ble_uuid128_t)))) { - NIMBLE_LOGC(LOG_TAG, "Error, no mem"); - abort(); + NIMBLE_LOGE(LOG_TAG, "Error, no mem"); + return false; } memcpy((void*)&m_advData.uuids128[m_advData.num_uuids128], &it.getNative()->u128, sizeof(ble_uuid128_t)); @@ -762,7 +772,7 @@ int NimBLEAdvertising::handleGapEvent(struct ble_gap_event *event, void *arg) { case BLE_HS_EOS: case BLE_HS_ECONTROLLER: case BLE_HS_ENOTSYNCED: - NIMBLE_LOGC(LOG_TAG, "host reset, rc=%d", event->adv_complete.reason); + NIMBLE_LOGE(LOG_TAG, "host reset, rc=%d", event->adv_complete.reason); NimBLEDevice::onReset(event->adv_complete.reason); return 0; default: @@ -800,9 +810,6 @@ void NimBLEAdvertisementData::addData(char * data, size_t length) { /** * @brief Set the appearance. * @param [in] appearance The appearance code value. - * - * See also: - * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml */ void NimBLEAdvertisementData::setAppearance(uint16_t appearance) { char cdata[2]; @@ -1069,4 +1076,12 @@ std::string NimBLEAdvertisementData::getPayload() { return m_payload; } // getPayload + +/** + * @brief Clear the advertisement data for reuse. + */ +void NimBLEAdvertisementData::clearData() { + m_payload.clear(); +} + #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER && !CONFIG_BT_NIMBLE_EXT_ADV */ diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertising.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertising.h index 14c34662c..dc36d0732 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertising.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAdvertising.h @@ -33,6 +33,7 @@ #include "NimBLEUUID.h" #include "NimBLEAddress.h" +#include #include /* COMPATIBILITY - DO NOT USE */ @@ -44,6 +45,9 @@ #define ESP_BLE_ADV_FLAG_NON_LIMIT_DISC (0x00 ) /* ************************* */ +class NimBLEAdvertising; + +typedef std::function advCompleteCB_t; /** * @brief Advertisement data set by the programmer to be published by the %BLE server. @@ -72,6 +76,7 @@ public: void addTxPower(); void setPreferredParams(uint16_t min, uint16_t max); std::string getPayload(); // Retrieve the current advert payload. + void clearData(); // Clear the advertisement data. private: friend class NimBLEAdvertising; @@ -92,7 +97,8 @@ public: void addServiceUUID(const NimBLEUUID &serviceUUID); void addServiceUUID(const char* serviceUUID); void removeServiceUUID(const NimBLEUUID &serviceUUID); - bool start(uint32_t duration = 0, void (*advCompleteCB)(NimBLEAdvertising *pAdv) = nullptr, NimBLEAddress* dirAddr = nullptr); + bool start(uint32_t duration = 0, advCompleteCB_t advCompleteCB = nullptr, NimBLEAddress* dirAddr = nullptr); + void removeServices(); bool stop(); void setAppearance(uint16_t appearance); void setName(const std::string &name); @@ -129,7 +135,7 @@ private: bool m_customScanResponseData; bool m_scanResp; bool m_advDataSet; - void (*m_advCompCB)(NimBLEAdvertising *pAdv); + advCompleteCB_t m_advCompCB{nullptr}; uint8_t m_slaveItvl[4]; uint32_t m_duration; std::vector m_svcData16; diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAttValue.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAttValue.h index be346d502..cc8599ab6 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAttValue.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEAttValue.h @@ -24,6 +24,7 @@ #include #include +#include #ifndef CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED # define CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED 0 @@ -41,7 +42,6 @@ # error CONFIG_NIMBLE_CPP_ATT_VALUE_INIT_LENGTH cannot be less than 1; Range = 1 : 512 #endif - /* Used to determine if the type passed to a template has a c_str() and length() method. */ template struct Has_c_str_len : std::false_type {}; @@ -266,7 +266,8 @@ public: /** @brief Subscript operator */ uint8_t operator [](int pos) const { - assert(pos < m_attr_len && "out of range"); return m_attr_value[pos]; } + NIMBLE_CPP_DEBUG_ASSERT(pos < m_attr_len); + return m_attr_value[pos]; } /** @brief Operator; Get the value as a std::vector. */ operator std::vector() const { @@ -311,7 +312,7 @@ public: inline NimBLEAttValue::NimBLEAttValue(uint16_t init_len, uint16_t max_len) { m_attr_value = (uint8_t*)calloc(init_len + 1, 1); - assert(m_attr_value && "No Mem"); + NIMBLE_CPP_DEBUG_ASSERT(m_attr_value); m_attr_max_len = std::min(BLE_ATT_ATTR_MAX_LEN, (int)max_len); m_attr_len = 0; m_capacity = init_len; @@ -354,7 +355,7 @@ inline NimBLEAttValue& NimBLEAttValue::operator =(const NimBLEAttValue & source) inline void NimBLEAttValue::deepCopy(const NimBLEAttValue & source) { uint8_t* res = (uint8_t*)realloc( m_attr_value, source.m_capacity + 1); - assert(res && "deepCopy: realloc failed"); + NIMBLE_CPP_DEBUG_ASSERT(res); ble_npl_hw_enter_critical(); m_attr_value = res; @@ -389,7 +390,7 @@ inline bool NimBLEAttValue::setValue(const uint8_t *value, uint16_t len) { res = (uint8_t*)realloc(m_attr_value, (len + 1)); m_capacity = len; } - assert(res && "setValue: realloc failed"); + NIMBLE_CPP_DEBUG_ASSERT(res); #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED time_t t = time(nullptr); @@ -424,7 +425,7 @@ inline NimBLEAttValue& NimBLEAttValue::append(const uint8_t *value, uint16_t len res = (uint8_t*)realloc(m_attr_value, (new_len + 1)); m_capacity = new_len; } - assert(res && "append: realloc failed"); + NIMBLE_CPP_DEBUG_ASSERT(res); #if CONFIG_NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED time_t t = time(nullptr); diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLECharacteristic.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLECharacteristic.cpp index f6db049de..82aa20fd1 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLECharacteristic.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLECharacteristic.cpp @@ -87,9 +87,7 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint3 */ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) { NimBLEDescriptor* pDescriptor = nullptr; - if(uuid == NimBLEUUID(uint16_t(0x2902))) { - assert(0 && "0x2902 descriptors cannot be manually created"); - } else if (uuid == NimBLEUUID(uint16_t(0x2904))) { + if (uuid == NimBLEUUID(uint16_t(0x2904))) { pDescriptor = new NimBLE2904(this); } else { pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this); @@ -266,7 +264,7 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han NIMBLE_LOGW(LOG_TAG, "Conn_handle (%d) is above the maximum value (%d)", conn_handle, BLE_HCI_LE_CONN_HANDLE_MAX); return BLE_ATT_ERR_INVALID_HANDLE; } - + const ble_uuid_t *uuid; int rc; NimBLEConnInfo peerInfo; @@ -279,12 +277,12 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){ switch(ctxt->op) { case BLE_GATT_ACCESS_OP_READ_CHR: { - rc = ble_gap_conn_find(conn_handle, &peerInfo.m_desc); - assert(rc == 0); + ble_gap_conn_find(conn_handle, &peerInfo.m_desc); // If the packet header is only 8 bytes this is a follow up of a long read // so we don't want to call the onRead() callback again. if(ctxt->om->om_pkthdr_len > 8 || + conn_handle == BLE_HS_CONN_HANDLE_NONE || pCharacteristic->m_value.size() <= (ble_att_mtu(peerInfo.m_desc.conn_handle) - 3)) { pCharacteristic->m_pCallbacks->onRead(pCharacteristic, peerInfo); } @@ -316,8 +314,8 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han len += next->om_len; next = SLIST_NEXT(next, om_next); } - rc = ble_gap_conn_find(conn_handle, &peerInfo.m_desc); - assert(rc == 0); + + ble_gap_conn_find(conn_handle, &peerInfo.m_desc); pCharacteristic->setValue(buf, len); pCharacteristic->m_pCallbacks->onWrite(pCharacteristic, peerInfo); return 0; diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEClient.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEClient.cpp index bd50e3221..e49827f42 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEClient.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEClient.cpp @@ -111,7 +111,7 @@ NimBLEClient::~NimBLEClient() { */ void NimBLEClient::dcTimerCb(ble_npl_event *event) { /* NimBLEClient *pClient = (NimBLEClient*)event->arg; - NIMBLE_LOGC(LOG_TAG, "Timed out disconnecting from %s - resetting host", + NIMBLE_LOGE(LOG_TAG, "Timed out disconnecting from %s - resetting host", std::string(pClient->getPeerAddress()).c_str()); */ ble_hs_sched_reset(BLE_HS_ECONTROLLER); @@ -189,7 +189,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttributes) NIMBLE_LOGD(LOG_TAG, ">> connect(%s)", address.toString().c_str()); if(!NimBLEDevice::m_synced) { - NIMBLE_LOGC(LOG_TAG, "Host reset, wait for sync."); + NIMBLE_LOGE(LOG_TAG, "Host reset, wait for sync."); return false; } @@ -458,9 +458,6 @@ void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterva // These are not used by NimBLE at this time - Must leave at defaults //m_pConnParams->min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units //m_pConnParams->max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units - - int rc = NimBLEUtils::checkConnParams(&m_pConnParams); - assert(rc == 0 && "Invalid Connection parameters"); } // setConnectionParams @@ -551,6 +548,66 @@ uint16_t NimBLEClient::getConnId() { return m_conn_id; } // getConnId +/** + * @brief Clear the connection information for this client. + * @note This is designed to be used to reset the connection information after + * calling setConnection(), and should not be used to disconnect from a + * peer. To disconnect from a peer, use disconnect(). + */ +void NimBLEClient::clearConnection() { + m_conn_id = BLE_HS_CONN_HANDLE_NONE; + m_connEstablished = false; + m_peerAddress = NimBLEAddress(); +} // clearConnection + +/** + * @brief Set the connection information for this client. + * @param [in] connInfo The connection information. + * @return True on success. + * @note Sets the connection established flag to true. + * @note If the client is already connected to a peer, this will return false. + * @note This is designed to be used when a connection is made outside of the + * NimBLEClient class, such as when a connection is made by the + * NimBLEServer class and the client is passed the connection id. This use + * enables the GATT Server to read the name of the device that has + * connected to it. + */ +bool NimBLEClient::setConnection(NimBLEConnInfo &connInfo) { + if (isConnected() || m_connEstablished) { + NIMBLE_LOGE(LOG_TAG, "Already connected"); + return false; + } + + m_peerAddress = connInfo.getAddress(); + m_conn_id = connInfo.getConnHandle(); + m_connEstablished = true; + + return true; +} // setConnection + +/** + * @brief Set the connection information for this client. + * @param [in] conn_id The connection id. + * @note Sets the connection established flag to true. + * @note This is designed to be used when a connection is made outside of the + * NimBLEClient class, such as when a connection is made by the + * NimBLEServer class and the client is passed the connection id. This use + * enables the GATT Server to read the name of the device that has + * connected to it. + * @note If the client is already connected to a peer, this will return false. + * @note This will look up the peer address using the connection id. + */ +bool NimBLEClient::setConnection(uint16_t conn_id) { + // we weren't provided the peer address, look it up using ble_gap_conn_find + NimBLEConnInfo connInfo; + int rc = ble_gap_conn_find(m_conn_id, &connInfo.m_desc); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Connection info not found"); + return false; + } + + return setConnection(connInfo); +} // setConnection /** * @brief Retrieve the address of the peer. @@ -945,7 +1002,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { case BLE_HS_ETIMEOUT_HCI: case BLE_HS_ENOTSYNCED: case BLE_HS_EOS: - NIMBLE_LOGC(LOG_TAG, "Disconnect - host reset, rc=%d", rc); + NIMBLE_LOGE(LOG_TAG, "Disconnect - host reset, rc=%d", rc); NimBLEDevice::onReset(rc); break; default: @@ -1111,7 +1168,11 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { { NimBLEConnInfo peerInfo; rc = ble_gap_conn_find(event->enc_change.conn_handle, &peerInfo.m_desc); - assert(rc == 0); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Connection info not found"); + rc = 0; + break; + } if (event->enc_change.status == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING)) { // Key is missing, try deleting. @@ -1125,6 +1186,19 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { break; } //BLE_GAP_EVENT_ENC_CHANGE + case BLE_GAP_EVENT_IDENTITY_RESOLVED: { + NimBLEConnInfo peerInfo; + rc = ble_gap_conn_find(event->identity_resolved.conn_handle, &peerInfo.m_desc); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Connection info not found"); + rc = 0; + break; + } + + pClient->m_pClientCallbacks->onIdentity(peerInfo); + break; + } // BLE_GAP_EVENT_IDENTITY_RESOLVED + case BLE_GAP_EVENT_MTU: { if(pClient->m_conn_id != event->mtu.conn_handle){ return 0; @@ -1143,20 +1217,17 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { if(pClient->m_conn_id != event->passkey.conn_handle) return 0; - if (event->passkey.params.action == BLE_SM_IOACT_DISP) { - pkey.action = event->passkey.params.action; - pkey.passkey = NimBLEDevice::m_passkey; // This is the passkey to be entered on peer - rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); - NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); + NimBLEConnInfo peerInfo; + rc = ble_gap_conn_find(event->passkey.conn_handle, &peerInfo.m_desc); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Connection info not found"); + rc = 0; + break; + } - } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { + if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp); - pkey.action = event->passkey.params.action; - pkey.numcmp_accept = pClient->m_pClientCallbacks->onConfirmPIN(event->passkey.params.numcmp); - - rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); - NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); - + pClient->m_pClientCallbacks->onConfirmPIN(peerInfo, event->passkey.params.numcmp); //TODO: Handle out of band pairing } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { static uint8_t tem_oob[16] = {0}; @@ -1169,12 +1240,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { //////// } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) { NIMBLE_LOGD(LOG_TAG, "Enter the passkey"); - pkey.action = event->passkey.params.action; - pkey.passkey = pClient->m_pClientCallbacks->onPassKeyRequest(); - - rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); - NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); - + pClient->m_pClientCallbacks->onPassKeyEntry(peerInfo); } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { NIMBLE_LOGD(LOG_TAG, "No passkey action required"); } @@ -1261,17 +1327,22 @@ bool NimBLEClientCallbacks::onConnParamsUpdateRequest(NimBLEClient* pClient, con return true; } -uint32_t NimBLEClientCallbacks::onPassKeyRequest(){ - NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyRequest: default: 123456"); - return 123456; -} +void NimBLEClientCallbacks::onPassKeyEntry(const NimBLEConnInfo& connInfo){ + NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyEntry: default: 123456"); + NimBLEDevice::injectPassKey(connInfo, 123456); +} //onPassKeyEntry -void NimBLEClientCallbacks::onAuthenticationComplete(NimBLEConnInfo& peerInfo){ +void NimBLEClientCallbacks::onAuthenticationComplete(const NimBLEConnInfo& connInfo){ NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default"); } -bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){ + +void NimBLEClientCallbacks::onIdentity(const NimBLEConnInfo& connInfo){ + NIMBLE_LOGD("NimBLEClientCallbacks", "onIdentity: default"); +} // onIdentity + +void NimBLEClientCallbacks::onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin){ NIMBLE_LOGD("NimBLEClientCallbacks", "onConfirmPIN: default: true"); - return true; + NimBLEDevice::injectConfirmPIN(connInfo, true); } #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */ diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEClient.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEClient.h index 486b3d0b5..acef487bf 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEClient.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEClient.h @@ -61,6 +61,9 @@ public: bool deleteCallbacks = true); std::string toString(); uint16_t getConnId(); + void clearConnection(); + bool setConnection(NimBLEConnInfo &conn_info); + bool setConnection(uint16_t conn_id); uint16_t getMTU(); bool secureConnection(); void setConnectTimeout(uint32_t timeout); @@ -144,23 +147,29 @@ public: /** * @brief Called when server requests a passkey for pairing. - * @return The passkey to be sent to the server. + * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. */ - virtual uint32_t onPassKeyRequest(); + virtual void onPassKeyEntry(const NimBLEConnInfo& connInfo); /** * @brief Called when the pairing procedure is complete. * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.\n * This can be used to check the status of the connection encryption/pairing. */ - virtual void onAuthenticationComplete(NimBLEConnInfo& connInfo); + virtual void onAuthenticationComplete(const NimBLEConnInfo& connInfo); /** * @brief Called when using numeric comparision for pairing. + * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. * @param [in] pin The pin to compare with the server. - * @return True to accept the pin. */ - virtual bool onConfirmPIN(uint32_t pin); + virtual void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin); + + /** + * @brief Called when the peer identity address is resolved. + * @param [in] connInfo A reference to a NimBLEConnInfo instance with information + */ + virtual void onIdentity(const NimBLEConnInfo& connInfo); }; #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */ diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEConnInfo.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEConnInfo.h index c764c2462..274e6d3b0 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEConnInfo.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEConnInfo.h @@ -12,47 +12,47 @@ friend class NimBLEClient; friend class NimBLECharacteristic; friend class NimBLEDescriptor; - ble_gap_conn_desc m_desc; - NimBLEConnInfo() { m_desc = {}; } - NimBLEConnInfo(ble_gap_conn_desc desc) { m_desc = desc; } + ble_gap_conn_desc m_desc{}; + NimBLEConnInfo(){}; + NimBLEConnInfo(ble_gap_conn_desc desc) { m_desc = desc; } public: /** @brief Gets the over-the-air address of the connected peer */ - NimBLEAddress getAddress() { return NimBLEAddress(m_desc.peer_ota_addr); } + NimBLEAddress getAddress() const { return NimBLEAddress(m_desc.peer_ota_addr); } /** @brief Gets the ID address of the connected peer */ - NimBLEAddress getIdAddress() { return NimBLEAddress(m_desc.peer_id_addr); } + NimBLEAddress getIdAddress() const { return NimBLEAddress(m_desc.peer_id_addr); } - /** @brief Gets the connection handle of the connected peer */ - uint16_t getConnHandle() { return m_desc.conn_handle; } + /** @brief Gets the connection handle (also known as the connection id) of the connected peer */ + uint16_t getConnHandle() const { return m_desc.conn_handle; } /** @brief Gets the connection interval for this connection (in 1.25ms units) */ - uint16_t getConnInterval() { return m_desc.conn_itvl; } + uint16_t getConnInterval() const { return m_desc.conn_itvl; } /** @brief Gets the supervision timeout for this connection (in 10ms units) */ - uint16_t getConnTimeout() { return m_desc.supervision_timeout; } + uint16_t getConnTimeout() const { return m_desc.supervision_timeout; } /** @brief Gets the allowable latency for this connection (unit = number of intervals) */ - uint16_t getConnLatency() { return m_desc.conn_latency; } + uint16_t getConnLatency() const { return m_desc.conn_latency; } /** @brief Gets the maximum transmission unit size for this connection (in bytes) */ - uint16_t getMTU() { return ble_att_mtu(m_desc.conn_handle); } + uint16_t getMTU() const { return ble_att_mtu(m_desc.conn_handle); } /** @brief Check if we are in the master role in this connection */ - bool isMaster() { return (m_desc.role == BLE_GAP_ROLE_MASTER); } + bool isMaster() const { return (m_desc.role == BLE_GAP_ROLE_MASTER); } /** @brief Check if we are in the slave role in this connection */ - bool isSlave() { return (m_desc.role == BLE_GAP_ROLE_SLAVE); } + bool isSlave() const { return (m_desc.role == BLE_GAP_ROLE_SLAVE); } /** @brief Check if we are connected to a bonded peer */ - bool isBonded() { return (m_desc.sec_state.bonded == 1); } + bool isBonded() const { return (m_desc.sec_state.bonded == 1); } /** @brief Check if the connection in encrypted */ - bool isEncrypted() { return (m_desc.sec_state.encrypted == 1); } + bool isEncrypted() const { return (m_desc.sec_state.encrypted == 1); } /** @brief Check if the the connection has been authenticated */ - bool isAuthenticated() { return (m_desc.sec_state.authenticated == 1); } + bool isAuthenticated() const { return (m_desc.sec_state.authenticated == 1); } /** @brief Gets the key size used to encrypt the connection */ - uint8_t getSecKeySize() { return m_desc.sec_state.key_size; } + uint8_t getSecKeySize() const { return m_desc.sec_state.key_size; } }; #endif diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDescriptor.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDescriptor.cpp index 28a151315..a457782a8 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDescriptor.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDescriptor.cpp @@ -55,7 +55,14 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_ m_pCharacteristic = pCharacteristic; m_pCallbacks = &defaultCallbacks; // No initial callback. m_properties = 0; - m_removed = 0; + + // Check if this is the client configuration descriptor and set to removed if true. + if (uuid == NimBLEUUID((uint16_t)0x2902)) { + NIMBLE_LOGW(LOG_TAG, "Manually created 2902 descriptor has no functionality; please remove."); + m_removed = 1; + } else { + m_removed = 0; + } if (properties & BLE_GATT_CHR_F_READ) { // convert uint16_t properties to uint8_t m_properties |= BLE_ATT_F_READ; @@ -155,7 +162,7 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, const ble_uuid_t *uuid; int rc; - NimBLEConnInfo peerInfo; + NimBLEConnInfo peerInfo{}; NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg; NIMBLE_LOGD(LOG_TAG, "Descriptor %s %s event", pDescriptor->getUUID().toString().c_str(), @@ -165,12 +172,12 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){ switch(ctxt->op) { case BLE_GATT_ACCESS_OP_READ_DSC: { - rc = ble_gap_conn_find(conn_handle, &peerInfo.m_desc); - assert(rc == 0); + ble_gap_conn_find(conn_handle, &peerInfo.m_desc); // If the packet header is only 8 bytes this is a follow up of a long read // so we don't want to call the onRead() callback again. if(ctxt->om->om_pkthdr_len > 8 || + conn_handle == BLE_HS_CONN_HANDLE_NONE || pDescriptor->m_value.size() <= (ble_att_mtu(peerInfo.getConnHandle()) - 3)) { pDescriptor->m_pCallbacks->onRead(pDescriptor, peerInfo); } @@ -182,11 +189,9 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, } case BLE_GATT_ACCESS_OP_WRITE_DSC: { - rc = ble_gap_conn_find(conn_handle, &peerInfo.m_desc); - assert(rc == 0); + ble_gap_conn_find(conn_handle, &peerInfo.m_desc); uint16_t att_max_len = pDescriptor->m_value.max_size(); - if (ctxt->om->om_len > att_max_len) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.cpp index eb9c17703..d14ce62d7 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.cpp @@ -299,7 +299,7 @@ size_t NimBLEDevice::getClientListSize() { /** * @brief Get a reference to a client by connection ID. * @param [in] conn_id The client connection ID to search for. - * @return A pointer to the client object with the spcified connection ID. + * @return A pointer to the client object with the specified connection ID or nullptr. */ /* STATIC */ NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) { @@ -308,7 +308,7 @@ NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) { return (*it); } } - assert(0); + return nullptr; } // getClientByID @@ -567,10 +567,16 @@ int NimBLEDevice::getNumBonds() { /** * @brief Deletes all bonding information. + * @returns true on success, false on failure. */ /*STATIC*/ -void NimBLEDevice::deleteAllBonds() { - ble_store_clear(); +bool NimBLEDevice::deleteAllBonds() { + int rc = ble_store_clear(); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed to delete all bonds; rc=%d", rc); + return false; + } + return true; } @@ -685,6 +691,7 @@ bool NimBLEDevice::whiteListAdd(const NimBLEAddress & address) { int rc = ble_gap_wl_set(&wlVec[0], wlVec.size()); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "Failed adding to whitelist rc=%d", rc); + m_whiteList.pop_back(); return false; } @@ -771,7 +778,7 @@ void NimBLEDevice::onReset(int reason) m_synced = false; - NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason, + NIMBLE_LOGE(LOG_TAG, "Resetting state; reason=%d, %s", reason, NimBLEUtils::returnCodeToString(reason)); #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) @@ -799,7 +806,10 @@ void NimBLEDevice::onSync(void) /* Make sure we have proper identity address set (public preferred) */ int rc = ble_hs_util_ensure_addr(0); - assert(rc == 0); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "error ensuring address; rc=%d", rc); + return; + } #ifndef ESP_PLATFORM rc = ble_hs_id_infer_auto(m_own_addr_type, &m_own_addr_type); @@ -871,9 +881,11 @@ void NimBLEDevice::init(const std::string &deviceName) { ESP_ERROR_CHECK(errRc); +#if CONFIG_IDF_TARGET_ESP32 esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); +#endif -#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) | !defined(CONFIG_NIMBLE_CPP_IDF) esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); # if defined (CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) bt_cfg.bluetooth_mode = ESP_BT_MODE_BLE; @@ -902,14 +914,16 @@ void NimBLEDevice::init(const std::string &deviceName) { ble_hs_cfg.sm_bonding = 0; ble_hs_cfg.sm_mitm = 0; ble_hs_cfg.sm_sc = 1; - ble_hs_cfg.sm_our_key_dist = 1; - ble_hs_cfg.sm_their_key_dist = 3; + ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + ble_hs_cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/ // Set the device name. rc = ble_svc_gap_device_name_set(deviceName.c_str()); - assert(rc == 0); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_svc_gap_device_name_set() failed; rc=%d", rc); + } ble_store_config_init(); @@ -935,13 +949,13 @@ void NimBLEDevice::deinit(bool clearAll) { int ret = nimble_port_stop(); if (ret == 0) { nimble_port_deinit(); -#ifdef ESP_PLATFORM -#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) +#ifdef CONFIG_NIMBLE_CPP_IDF +# if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) ret = esp_nimble_hci_and_controller_deinit(); if (ret != ESP_OK) { NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", ret); } -#endif +# endif #endif initialized = false; m_synced = false; @@ -1150,6 +1164,43 @@ int NimBLEDevice::startSecurity(uint16_t conn_id) { } // startSecurity +/** + * @brief Inject the provided passkey into the Security Manager + * @param [in] peerInfo Connection information for the peer + * @param [in] pin The 6-digit pin to inject + * @return true if the passkey was injected successfully. + */ +bool NimBLEDevice::injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t pin) { + int rc = 0; + struct ble_sm_io pkey = {0,0}; + + pkey.action = BLE_SM_IOACT_INPUT; + pkey.passkey = pin; + + rc = ble_sm_inject_io(peerInfo.getConnHandle(), &pkey); + NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc); + return rc == 0; +} + + +/** + * @brief Inject the provided numeric comparison response into the Security Manager + * @param [in] peerInfo Connection information for the peer + * @param [in] accept Whether the user confirmed or declined the comparison + */ +bool NimBLEDevice::injectConfirmPIN(const NimBLEConnInfo& peerInfo, bool accept) { + int rc = 0; + struct ble_sm_io pkey = {0,0}; + + pkey.action = BLE_SM_IOACT_NUMCMP; + pkey.numcmp_accept = accept; + + rc = ble_sm_inject_io(peerInfo.getConnHandle(), &pkey); + NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc); + return rc == 0; +} + + /** * @brief Check if the device address is on our ignore list. * @param [in] address The address to look for. @@ -1202,10 +1253,22 @@ void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) { int rc = ble_gap_event_listener_register(&m_listener, m_customGapHandler, NULL); if(rc == BLE_HS_EALREADY){ NIMBLE_LOGI(LOG_TAG, "Already listening to GAP events."); + } else if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gap_event_listener_register: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); } - else{ - assert(rc == 0); - } + } // setCustomGapHandler -#endif // CONFIG_BT_ENABLED +#if CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED || __DOXYGEN__ +/** + * @brief Debug assert - weak function. + * @param [in] file The file where the assert occurred. + * @param [in] line The line number where the assert occurred. + */ +void nimble_cpp_assert(const char *file, unsigned line) { + NIMBLE_LOGC("", "Assertion failed at %s:%u\n", file, line); + abort(); +} +#endif // CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED + +#endif // CONFIG_BT_ENABLED \ No newline at end of file diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.h index ddb7a60c5..64bd4ed34 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.h @@ -136,6 +136,8 @@ public: static void setSecurityPasskey(uint32_t pin); static uint32_t getSecurityPasskey(); static int startSecurity(uint16_t conn_id); + static bool injectConfirmPIN(const NimBLEConnInfo& peerInfo, bool accept); + static bool injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t pin); static int setMTU(uint16_t mtu); static uint16_t getMTU(); static bool isIgnored(const NimBLEAddress &address); @@ -172,7 +174,7 @@ public: static bool deleteBond(const NimBLEAddress &address); static int getNumBonds(); static bool isBonded(const NimBLEAddress &address); - static void deleteAllBonds(); + static bool deleteAllBonds(); static NimBLEAddress getBondedAddress(int index); #endif diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEEddystoneTLM.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEEddystoneTLM.cpp index 7a9c5102c..1f48a1609 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEEddystoneTLM.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEEddystoneTLM.cpp @@ -81,7 +81,7 @@ uint16_t NimBLEEddystoneTLM::getVolt() { * @return The temperature value. */ float NimBLEEddystoneTLM::getTemp() { - return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f; + return (int16_t)ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f; } // getTemp /** @@ -203,7 +203,7 @@ void NimBLEEddystoneTLM::setVolt(uint16_t volt) { * @param [in] temp The temperature value. */ void NimBLEEddystoneTLM::setTemp(float temp) { - m_eddystoneData.temp = (uint16_t)temp; + m_eddystoneData.temp = ENDIAN_CHANGE_U16((int16_t)(temp * 256.0f)); } // setTemp diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEExtAdvertising.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEExtAdvertising.cpp index b979c9fd0..67d8a586a 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEExtAdvertising.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEExtAdvertising.cpp @@ -341,7 +341,7 @@ int NimBLEExtAdvertising::handleGapEvent(struct ble_gap_event *event, void *arg) case BLE_HS_EOS: case BLE_HS_ECONTROLLER: case BLE_HS_ENOTSYNCED: - NIMBLE_LOGC(LOG_TAG, "host reset, rc = %d", event->adv_complete.reason); + NIMBLE_LOGE(LOG_TAG, "host reset, rc = %d", event->adv_complete.reason); NimBLEDevice::onReset(event->adv_complete.reason); return 0; default: @@ -623,9 +623,6 @@ void NimBLEExtAdvertisement::addData(const uint8_t * data, size_t length) { /** * @brief Set the appearance. * @param [in] appearance The appearance code value. - * - * See also: - * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml */ void NimBLEExtAdvertisement::setAppearance(uint16_t appearance) { char cdata[2]; diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEHIDDevice.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEHIDDevice.cpp index a2310eb9e..12c14def1 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEHIDDevice.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEHIDDevice.cpp @@ -26,28 +26,34 @@ NimBLEHIDDevice::NimBLEHIDDevice(NimBLEServer* server) { /* * Here we create mandatory services described in bluetooth specification */ - m_deviceInfoService = server->createService(NimBLEUUID((uint16_t) 0x180a)); - m_hidService = server->createService(NimBLEUUID((uint16_t) 0x1812)); - m_batteryService = server->createService(NimBLEUUID((uint16_t) 0x180f)); + m_deviceInfoService = server->createService(NimBLEUUID((uint16_t)0x180a)); + m_hidService = server->createService(NimBLEUUID((uint16_t)0x1812)); + m_batteryService = server->createService(NimBLEUUID((uint16_t)0x180f)); /* * Mandatory characteristic for device info service */ - m_pnpCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a50, NIMBLE_PROPERTY::READ); + m_pnpCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t)0x2a50, NIMBLE_PROPERTY::READ); + + /* + * Non-mandatory characteristics for device info service + * Will be created on demand + */ + m_manufacturerCharacteristic = nullptr; /* * Mandatory characteristics for HID service */ - m_hidInfoCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4a, NIMBLE_PROPERTY::READ); - m_reportMapCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4b, NIMBLE_PROPERTY::READ); - m_hidControlCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4c, NIMBLE_PROPERTY::WRITE_NR); - m_protocolModeCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4e, NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ); + m_hidInfoCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4a, NIMBLE_PROPERTY::READ); + m_reportMapCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4b, NIMBLE_PROPERTY::READ); + m_hidControlCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4c, NIMBLE_PROPERTY::WRITE_NR); + m_protocolModeCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4e, NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ); /* * Mandatory battery level characteristic with notification and presence descriptor */ - m_batteryLevelCharacteristic = m_batteryService->createCharacteristic((uint16_t) 0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); - NimBLE2904* batteryLevelDescriptor = (NimBLE2904*)m_batteryLevelCharacteristic->createDescriptor((uint16_t) 0x2904); + m_batteryLevelCharacteristic = m_batteryService->createCharacteristic((uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); + NimBLE2904 *batteryLevelDescriptor = (NimBLE2904*)m_batteryLevelCharacteristic->createDescriptor((uint16_t)0x2904); batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8); batteryLevelDescriptor->setNamespace(1); batteryLevelDescriptor->setUnit(0x27ad); @@ -56,8 +62,8 @@ NimBLEHIDDevice::NimBLEHIDDevice(NimBLEServer* server) { * This value is setup here because its default value in most usage cases, its very rare to use boot mode * and we want to simplify library using as much as possible */ - const uint8_t pMode[] = { 0x01 }; - protocolMode()->setValue((uint8_t*) pMode, 1); + const uint8_t pMode[] = {0x01}; + protocolMode()->setValue((uint8_t*)pMode, 1); } NimBLEHIDDevice::~NimBLEHIDDevice() { @@ -86,7 +92,10 @@ void NimBLEHIDDevice::startServices() { * @brief Create a manufacturer characteristic (this characteristic is optional). */ NimBLECharacteristic* NimBLEHIDDevice::manufacturer() { - m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a29, NIMBLE_PROPERTY::READ); + if (m_manufacturerCharacteristic == nullptr) { + m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t)0x2a29, NIMBLE_PROPERTY::READ); + } + return m_manufacturerCharacteristic; } @@ -95,7 +104,7 @@ NimBLECharacteristic* NimBLEHIDDevice::manufacturer() { * @param [in] name The manufacturer name of this HID device. */ void NimBLEHIDDevice::manufacturer(std::string name) { - m_manufacturerCharacteristic->setValue(name); + manufacturer()->setValue(name); } /** @@ -106,7 +115,15 @@ void NimBLEHIDDevice::manufacturer(std::string name) { * @param [in] version The produce version number. */ void NimBLEHIDDevice::pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version) { - uint8_t pnp[] = { sig, (uint8_t) (vid >> 8), (uint8_t) vid, (uint8_t) (pid >> 8), (uint8_t) pid, (uint8_t) (version >> 8), (uint8_t) version }; + uint8_t pnp[] = { + sig, + ((uint8_t*)&vid)[0], + ((uint8_t*)&vid)[1], + ((uint8_t*)&pid)[0], + ((uint8_t*)&pid)[1], + ((uint8_t*)&version)[0], + ((uint8_t*)&version)[1] + }; m_pnpCharacteristic->setValue(pnp, sizeof(pnp)); } @@ -116,7 +133,7 @@ void NimBLEHIDDevice::pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t vers * @param [in] flags The HID Class Specification release number to use. */ void NimBLEHIDDevice::hidInfo(uint8_t country, uint8_t flags) { - uint8_t info[] = { 0x11, 0x1, country, flags }; + uint8_t info[] = {0x11, 0x1, country, flags}; m_hidInfoCharacteristic->setValue(info, sizeof(info)); } @@ -126,11 +143,11 @@ void NimBLEHIDDevice::hidInfo(uint8_t country, uint8_t flags) { * @return pointer to new input report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::inputReport(uint8_t reportID) { - NimBLECharacteristic* inputReportCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ_ENC); - NimBLEDescriptor* inputReportDescriptor = inputReportCharacteristic->createDescriptor((uint16_t) 0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC); + NimBLECharacteristic *inputReportCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ_ENC); + NimBLEDescriptor *inputReportDescriptor = inputReportCharacteristic->createDescriptor((uint16_t)0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC); - uint8_t desc1_val[] = { reportID, 0x01 }; - inputReportDescriptor->setValue((uint8_t*) desc1_val, 2); + uint8_t desc1_val[] = {reportID, 0x01}; + inputReportDescriptor->setValue((uint8_t*)desc1_val, 2); return inputReportCharacteristic; } @@ -141,11 +158,11 @@ NimBLECharacteristic* NimBLEHIDDevice::inputReport(uint8_t reportID) { * @return Pointer to new output report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::outputReport(uint8_t reportID) { - NimBLECharacteristic* outputReportCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); - NimBLEDescriptor* outputReportDescriptor = outputReportCharacteristic->createDescriptor((uint16_t) 0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLECharacteristic *outputReportCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLEDescriptor *outputReportDescriptor = outputReportCharacteristic->createDescriptor((uint16_t)0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); - uint8_t desc1_val[] = { reportID, 0x02 }; - outputReportDescriptor->setValue((uint8_t*) desc1_val, 2); + uint8_t desc1_val[] = {reportID, 0x02}; + outputReportDescriptor->setValue((uint8_t*)desc1_val, 2); return outputReportCharacteristic; } @@ -156,11 +173,11 @@ NimBLECharacteristic* NimBLEHIDDevice::outputReport(uint8_t reportID) { * @return Pointer to new feature report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::featureReport(uint8_t reportID) { - NimBLECharacteristic* featureReportCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); - NimBLEDescriptor* featureReportDescriptor = featureReportCharacteristic->createDescriptor((uint16_t) 0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLECharacteristic *featureReportCharacteristic = m_hidService->createCharacteristic((uint16_t)0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); + NimBLEDescriptor *featureReportDescriptor = featureReportCharacteristic->createDescriptor((uint16_t)0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC); - uint8_t desc1_val[] = { reportID, 0x03 }; - featureReportDescriptor->setValue((uint8_t*) desc1_val, 2); + uint8_t desc1_val[] = {reportID, 0x03}; + featureReportDescriptor->setValue((uint8_t*)desc1_val, 2); return featureReportCharacteristic; } @@ -169,14 +186,14 @@ NimBLECharacteristic* NimBLEHIDDevice::featureReport(uint8_t reportID) { * @brief Creates a keyboard boot input report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::bootInput() { - return m_hidService->createCharacteristic((uint16_t) 0x2a22, NIMBLE_PROPERTY::NOTIFY); + return m_hidService->createCharacteristic((uint16_t)0x2a22, NIMBLE_PROPERTY::NOTIFY); } /** * @brief Create a keyboard boot output report characteristic */ NimBLECharacteristic* NimBLEHIDDevice::bootOutput() { - return m_hidService->createCharacteristic((uint16_t) 0x2a32, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR); + return m_hidService->createCharacteristic((uint16_t)0x2a32, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR); } /** diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEHIDDevice.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEHIDDevice.h index 0e8b2828a..6461a4f32 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEHIDDevice.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEHIDDevice.h @@ -33,6 +33,7 @@ #define HID_DIGITAL_PEN 0x03C7 #define HID_BARCODE 0x03C8 +#define PNPVersionField(MajorVersion, MinorVersion, PatchVersion) ((MajorVersion << 16) & 0xFF00) | ((MinorVersion << 8) & 0x00F0) | (PatchVersion & 0x000F) /** * @brief A model of a %BLE Human Interface Device. diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLELog.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLELog.h index 542e3d982..0ccdf4163 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLELog.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLELog.h @@ -14,6 +14,7 @@ #if defined(CONFIG_NIMBLE_CPP_IDF) // using esp-idf # include "esp_log.h" +# include "console/console.h" # ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL # define CONFIG_NIMBLE_CPP_LOG_LEVEL 0 # endif @@ -35,22 +36,6 @@ # define NIMBLE_LOGE(tag, format, ...) \ NIMBLE_CPP_LOG_PRINT(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__) -# define NIMBLE_LOGC(tag, format, ...) \ - NIMBLE_CPP_LOG_PRINT(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__) - -// These defines pollute the global namespace and conflict with Tasmota and basically always turn on `seriallog 3` -#ifdef LOG_LEVEL_DEBUG -#undef LOG_LEVEL_DEBUG -#endif - -#ifdef LOG_LEVEL_INFO -#undef LOG_LEVEL_INFO -#endif - -#ifdef LOG_LEVEL_ERROR -#undef LOG_LEVEL_ERROR -#endif - #else // using Arduino # include "nimble/porting/nimble/include/syscfg/syscfg.h" # include "nimble/console/console.h" @@ -82,12 +67,13 @@ # if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 1 # define NIMBLE_LOGE( tag, format, ... ) console_printf("E %s: " format "\n", tag, ##__VA_ARGS__) -# define NIMBLE_LOGC( tag, format, ... ) console_printf("CRIT %s: " format "\n", tag, ##__VA_ARGS__) # else # define NIMBLE_LOGE( tag, format, ... ) (void)tag -# define NIMBLE_LOGC( tag, format, ... ) (void)tag # endif #endif /* CONFIG_NIMBLE_CPP_IDF */ + +#define NIMBLE_LOGC( tag, format, ... ) console_printf("CRIT %s: " format "\n", tag, ##__VA_ARGS__) + #endif /* CONFIG_BT_ENABLED */ #endif /* MAIN_NIMBLELOG_H_ */ diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEScan.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEScan.cpp index c7ee07a0f..b4fe6a921 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEScan.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEScan.cpp @@ -359,7 +359,7 @@ bool NimBLEScan::start(uint32_t duration, bool is_continue) { case BLE_HS_EOS: case BLE_HS_ECONTROLLER: case BLE_HS_ENOTSYNCED: - NIMBLE_LOGC(LOG_TAG, "Unable to scan - Host Reset"); + NIMBLE_LOGE(LOG_TAG, "Unable to scan - Host Reset"); break; default: @@ -459,7 +459,7 @@ void NimBLEScan::onHostSync() { /** * @brief Start scanning and block until scanning has been completed. - * @param [in] duration The duration in seconds for which to scan. + * @param [in] duration The duration in milliseconds for which to scan. * @param [in] is_continue Set to true to save previous scan results, false to clear them. * @return The scan results. */ diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEServer.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEServer.cpp index daa5f2359..15f933c3f 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEServer.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEServer.cpp @@ -27,6 +27,11 @@ #include "nimble/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h" #endif +#include + +#define NIMBLE_SERVER_GET_PEER_NAME_ON_CONNECT_CB 0 +#define NIMBLE_SERVER_GET_PEER_NAME_ON_AUTH_CB 1 + static const char* LOG_TAG = "NimBLEServer"; static NimBLEServerCallbacks defaultCallbacks; @@ -47,6 +52,7 @@ NimBLEServer::NimBLEServer() { #endif m_svcChanged = false; m_deleteCallbacks = true; + m_getPeerNameOnConnect = false; } // NimBLEServer @@ -186,9 +192,8 @@ void NimBLEServer::start() { int rc = ble_gatts_start(); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc, - NimBLEUtils::returnCodeToString(rc)); - abort(); + NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + return; } #if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 4 @@ -215,7 +220,9 @@ void NimBLEServer::start() { if(svc->m_removed == 0) { rc = ble_gatts_find_svc(&svc->getUUID().getNative()->u, &svc->m_handle); if(rc != 0) { - abort(); + NIMBLE_LOGW(LOG_TAG, "GATT Server started without service: %s, Service %s", + svc->getUUID().toString().c_str(), svc->isStarted() ? "missing" : "not started"); + continue; // Skip this service as it was not started } } @@ -252,6 +259,15 @@ int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) { return rc; } // disconnect +/** + * @brief Disconnect the specified client with optional reason. + * @param [in] connInfo Connection of the client to disconnect. + * @param [in] reason code for disconnecting. + * @return NimBLE host return code. + */ +int NimBLEServer::disconnect(const NimBLEConnInfo &connInfo, uint8_t reason) { + return disconnect(connInfo.getConnHandle(), reason); +} // disconnect #if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_) /** @@ -263,6 +279,15 @@ void NimBLEServer::advertiseOnDisconnect(bool aod) { } // advertiseOnDisconnect #endif +/** + * @brief Set the server to automatically read the name from the connected peer before + * the onConnect callback is called and enables the override callback with name parameter. + * @param [in] enable Enable reading the connected peer name upon connection. + */ +void NimBLEServer::getPeerNameOnConnect(bool enable) { + m_getPeerNameOnConnect = enable; +} // getPeerNameOnConnect + /** * @brief Return the number of connected clients. * @return The number of connected clients. @@ -328,6 +353,113 @@ NimBLEConnInfo NimBLEServer::getPeerIDInfo(uint16_t id) { return peerInfo; } // getPeerIDInfo +/** + * @brief Callback that is called after reading from the peer name characteristic. + * @details This will check the task pointer in the task data struct to determine + * the action to take once the name has been read. If there is a task waiting then + * it will be woken, if not, the the RC value is checked to determine which callback + * should be called. + */ +int NimBLEServer::peerNameCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + std::string *name = (std::string*)pTaskData->buf; + int rc = error->status; + + if (rc == 0) { + if (attr) { + name->append(OS_MBUF_DATA(attr->om, char*), OS_MBUF_PKTLEN(attr->om)); + return rc; + } + } + + if (rc == BLE_HS_EDONE) { + // No ask means this was read for a callback. + if (pTaskData->task == nullptr) { + NimBLEServer* pServer = (NimBLEServer*)pTaskData->pATT; + NimBLEConnInfo peerInfo{}; + ble_gap_conn_find(conn_handle, &peerInfo.m_desc); + + // Use the rc value as a flag to indicate which callback should be called. + if (pTaskData->rc == NIMBLE_SERVER_GET_PEER_NAME_ON_CONNECT_CB) { + pServer->m_pServerCallbacks->onConnect(pServer, peerInfo, *name); + } else if (pTaskData->rc == NIMBLE_SERVER_GET_PEER_NAME_ON_AUTH_CB) { + pServer->m_pServerCallbacks->onAuthenticationComplete(peerInfo, *name); + } + } + } else { + NIMBLE_LOGE(LOG_TAG, "NimBLEServerPeerNameCB rc=%d; %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + + if (pTaskData->task != nullptr) { + pTaskData->rc = rc; + xTaskNotifyGive(pTaskData->task); + } else { + // If the read was triggered for callback use then these were allocated. + delete name; + delete pTaskData; + } + + return rc; +} + +/** + * @brief Internal method that sends the read command. + */ +std::string NimBLEServer::getPeerNameInternal(uint16_t conn_handle, TaskHandle_t task, int cb_type) { + std::string *buf = new std::string{}; + ble_task_data_t *taskData = new ble_task_data_t{this, task, cb_type, buf}; + ble_uuid16_t uuid {{BLE_UUID_TYPE_16}, BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME}; + int rc = ble_gattc_read_by_uuid(conn_handle, + 1, + 0xffff, + ((ble_uuid_t*)&uuid), + NimBLEServer::peerNameCB, + taskData); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gattc_read_by_uuid rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + NimBLEConnInfo peerInfo{}; + ble_gap_conn_find(conn_handle, &peerInfo.m_desc); + if (cb_type == NIMBLE_SERVER_GET_PEER_NAME_ON_CONNECT_CB) { + m_pServerCallbacks->onConnect(this, peerInfo, *buf); + } else if (cb_type == NIMBLE_SERVER_GET_PEER_NAME_ON_AUTH_CB) { + m_pServerCallbacks->onAuthenticationComplete(peerInfo, *buf); + } + delete buf; + delete taskData; + } else if (task != nullptr) { +#ifdef ulTaskNotifyValueClear + // Clear the task notification value to ensure we block + ulTaskNotifyValueClear(task, ULONG_MAX); +#endif + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData->rc; + std::string name{*(std::string*)taskData->buf}; + delete buf; + delete taskData; + + if (rc != 0 && rc != BLE_HS_EDONE) { + NIMBLE_LOGE(LOG_TAG, "getPeerName rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + + return name; + } + // TaskData and name buffer will be deleted in the callback. + return ""; +} + +/** + * @brief Get the name of the connected peer. + * @param connInfo A reference to a NimBLEConnInfo instance to read the name from. + * @returns A string containing the name. + * @note This is a blocking call and should NOT be called from any callbacks! + */ +std::string NimBLEServer::getPeerName(const NimBLEConnInfo& connInfo) { + std::string name = getPeerNameInternal(connInfo.getConnHandle(), xTaskGetCurrentTaskHandle()); + return name; +} /** * @brief Handle a GATT Server Event. @@ -354,16 +486,22 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { #if !CONFIG_BT_NIMBLE_EXT_ADV NimBLEDevice::startAdvertising(); #endif - } - else { - pServer->m_connectedPeersVec.push_back(event->connect.conn_handle); - + } else { rc = ble_gap_conn_find(event->connect.conn_handle, &peerInfo.m_desc); if (rc != 0) { return 0; } - pServer->m_pServerCallbacks->onConnect(pServer, peerInfo); + pServer->m_connectedPeersVec.push_back(event->connect.conn_handle); + + if (pServer->m_getPeerNameOnConnect) { + pServer->getPeerNameInternal(event->connect.conn_handle, + nullptr, + NIMBLE_SERVER_GET_PEER_NAME_ON_CONNECT_CB); + } else { + pServer->m_pServerCallbacks->onConnect(pServer, peerInfo); + } + } return 0; @@ -378,7 +516,7 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { case BLE_HS_EOS: case BLE_HS_ECONTROLLER: case BLE_HS_ENOTSYNCED: - NIMBLE_LOGC(LOG_TAG, "Disconnect - host reset, rc=%d", event->disconnect.reason); + NIMBLE_LOGE(LOG_TAG, "Disconnect - host reset, rc=%d", event->disconnect.reason); NimBLEDevice::onReset(event->disconnect.reason); break; default: @@ -514,10 +652,26 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { return BLE_ATT_ERR_INVALID_HANDLE; } - pServer->m_pServerCallbacks->onAuthenticationComplete(peerInfo); + if (pServer->m_getPeerNameOnConnect) { + pServer->getPeerNameInternal(event->enc_change.conn_handle, + nullptr, + NIMBLE_SERVER_GET_PEER_NAME_ON_AUTH_CB); + } else { + pServer->m_pServerCallbacks->onAuthenticationComplete(peerInfo); + } return 0; } // BLE_GAP_EVENT_ENC_CHANGE + case BLE_GAP_EVENT_IDENTITY_RESOLVED: { + rc = ble_gap_conn_find(event->identity_resolved.conn_handle, &peerInfo.m_desc); + if(rc != 0) { + return BLE_ATT_ERR_INVALID_HANDLE; + } + + pServer->m_pServerCallbacks->onIdentity(peerInfo); + return 0; + } // BLE_GAP_EVENT_IDENTITY_RESOLVED + case BLE_GAP_EVENT_PASSKEY_ACTION: { struct ble_sm_io pkey = {0,0}; @@ -528,19 +682,20 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { // if the (static)passkey is the default, check the callback for custom value // both values default to the same. if(pkey.passkey == 123456) { - pkey.passkey = pServer->m_pServerCallbacks->onPassKeyRequest(); + pkey.passkey = pServer->m_pServerCallbacks->onPassKeyDisplay(); } rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc); } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp); - pkey.action = event->passkey.params.action; - pkey.numcmp_accept = pServer->m_pServerCallbacks->onConfirmPIN(event->passkey.params.numcmp); - rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); - NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc); + rc = ble_gap_conn_find(event->passkey.conn_handle, &peerInfo.m_desc); + if(rc != 0) { + return BLE_ATT_ERR_INVALID_HANDLE; + } + pServer->m_pServerCallbacks->onConfirmPIN(peerInfo, event->passkey.params.numcmp); //TODO: Handle out of band pairing } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { static uint8_t tem_oob[16] = {0}; @@ -551,14 +706,6 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_OOB; ble_sm_inject_io result: %d", rc); ////////////////////////////////// - } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) { - NIMBLE_LOGD(LOG_TAG, "Enter the passkey"); - pkey.action = event->passkey.params.action; - pkey.passkey = pServer->m_pServerCallbacks->onPassKeyRequest(); - - rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); - NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc); - } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { NIMBLE_LOGD(LOG_TAG, "No passkey action required"); } @@ -842,6 +989,10 @@ void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, NimBLEConnInfo& con NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); } // onConnect +void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, std::string& name) { + NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); +} // onConnect + void NimBLEServerCallbacks::onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) { NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default"); @@ -851,18 +1002,26 @@ void NimBLEServerCallbacks::onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) NIMBLE_LOGD("NimBLEServerCallbacks", "onMTUChange(): Default"); } // onMTUChange -uint32_t NimBLEServerCallbacks::onPassKeyRequest(){ - NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyRequest: default: 123456"); +uint32_t NimBLEServerCallbacks::onPassKeyDisplay(){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyDisplay: default: 123456"); return 123456; -} //onPassKeyRequest +} //onPassKeyDisplay -void NimBLEServerCallbacks::onAuthenticationComplete(NimBLEConnInfo& connInfo){ +void NimBLEServerCallbacks::onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onConfirmPIN: default: true"); + NimBLEDevice::injectConfirmPIN(connInfo, true); +} // onConfirmPIN + +void NimBLEServerCallbacks::onIdentity(const NimBLEConnInfo& connInfo){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onIdentity: default"); +} // onIdentity + +void NimBLEServerCallbacks::onAuthenticationComplete(const NimBLEConnInfo& connInfo){ NIMBLE_LOGD("NimBLEServerCallbacks", "onAuthenticationComplete: default"); } // onAuthenticationComplete -bool NimBLEServerCallbacks::onConfirmPIN(uint32_t pin){ - NIMBLE_LOGD("NimBLEServerCallbacks", "onConfirmPIN: default: true"); - return true; -} // onConfirmPIN +void NimBLEServerCallbacks::onAuthenticationComplete(const NimBLEConnInfo& connInfo, const std::string& name){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onAuthenticationComplete: default"); +} // onAuthenticationComplete #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */ diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEServer.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEServer.h index ea56ed73f..bbb4ebfb9 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEServer.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEServer.h @@ -69,6 +69,8 @@ public: NimBLEService* getServiceByHandle(uint16_t handle); int disconnect(uint16_t connID, uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); + int disconnect(const NimBLEConnInfo &connInfo, + uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); void updateConnParams(uint16_t conn_handle, uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout); @@ -78,6 +80,8 @@ public: NimBLEConnInfo getPeerInfo(size_t index); NimBLEConnInfo getPeerInfo(const NimBLEAddress& address); NimBLEConnInfo getPeerIDInfo(uint16_t id); + std::string getPeerName(const NimBLEConnInfo& connInfo); + void getPeerNameOnConnect(bool enable); #if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_) void advertiseOnDisconnect(bool); #endif @@ -98,6 +102,7 @@ private: #if !CONFIG_BT_NIMBLE_EXT_ADV bool m_advertiseOnDisconnect; #endif + bool m_getPeerNameOnConnect; bool m_svcChanged; NimBLEServerCallbacks* m_pServerCallbacks; bool m_deleteCallbacks; @@ -110,10 +115,14 @@ private: std::vector m_notifyChrVec; static int handleGapEvent(struct ble_gap_event *event, void *arg); + static int peerNameCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); + std::string getPeerNameInternal(uint16_t conn_handle, TaskHandle_t task, int cb_type = -1); void serviceChanged(); void resetGATT(); bool setIndicateWait(uint16_t conn_handle); void clearIndicateWait(uint16_t conn_handle); + }; // NimBLEServer @@ -128,11 +137,21 @@ public: * @brief Handle a client connection. * This is called when a client connects. * @param [in] pServer A pointer to the %BLE server that received the client connection. - * @param [in] connInfo A reference to a NimBLEConnInfo instance with information + * @param [in] connInfo A reference to a NimBLEConnInfo instance with information. * about the peer connection parameters. */ virtual void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo); + /** + * @brief Handle a client connection. + * This is called when a client connects. + * @param [in] pServer A pointer to the %BLE server that received the client connection. + * @param [in] connInfo A reference to a NimBLEConnInfo instance with information. + * @param [in] name The name of the connected peer device. + * about the peer connection parameters. + */ + virtual void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, std::string& name); + /** * @brief Handle a client disconnection. * This is called when a client discconnects. @@ -152,24 +171,39 @@ public: virtual void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo); /** - * @brief Called when a client requests a passkey for pairing. + * @brief Called when a client requests a passkey for pairing (display). * @return The passkey to be sent to the client. */ - virtual uint32_t onPassKeyRequest(); + virtual uint32_t onPassKeyDisplay(); + + /** + * @brief Called when using numeric comparision for pairing. + * @param [in] connInfo A reference to a NimBLEConnInfo instance with information + * Should be passed back to NimBLEDevice::injectConfirmPIN + * @param [in] pin The pin to compare with the client. + */ + virtual void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin); /** * @brief Called when the pairing procedure is complete. * @param [in] connInfo A reference to a NimBLEConnInfo instance with information * about the peer connection parameters. */ - virtual void onAuthenticationComplete(NimBLEConnInfo& connInfo); + virtual void onAuthenticationComplete(const NimBLEConnInfo& connInfo); /** - * @brief Called when using numeric comparision for pairing. - * @param [in] pin The pin to compare with the client. - * @return True to accept the pin. + * @brief Called when the pairing procedure is complete. + * @param [in] connInfo A reference to a NimBLEConnInfo instance with information + * @param [in] name The name of the connected peer device. + * about the peer connection parameters. */ - virtual bool onConfirmPIN(uint32_t pin); + virtual void onAuthenticationComplete(const NimBLEConnInfo& connInfo, const std::string& name); + + /** + * @brief Called when the peer identity address is resolved. + * @param [in] connInfo A reference to a NimBLEConnInfo instance with information + */ + virtual void onIdentity(const NimBLEConnInfo& connInfo); }; // NimBLEServerCallbacks #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */ diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEService.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEService.cpp index 02195ace7..7c2decf01 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEService.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEService.cpp @@ -126,7 +126,7 @@ bool NimBLEService::start() { // Nimble requires an array of services to be sent to the api // Since we are adding 1 at a time we create an array of 2 and set the type // of the second service to 0 to indicate the end of the array. - ble_gatt_svc_def* svc = new ble_gatt_svc_def[2]; + ble_gatt_svc_def* svc = new ble_gatt_svc_def[2]{}; ble_gatt_chr_def* pChr_a = nullptr; ble_gatt_dsc_def* pDsc_a = nullptr; @@ -188,7 +188,7 @@ bool NimBLEService::start() { pChr_a[i].descriptors = NULL; } else { // Must have last descriptor uuid = 0 so we have to create 1 extra - pDsc_a = new ble_gatt_dsc_def[numDscs+1]; + pDsc_a = new ble_gatt_dsc_def[numDscs+1]{}; int d = 0; for(auto dsc_it = (*chr_it)->m_dscVec.begin(); dsc_it != (*chr_it)->m_dscVec.end(); ++dsc_it ) { if((*dsc_it)->m_removed > 0) { @@ -434,4 +434,14 @@ NimBLEServer* NimBLEService::getServer() { return NimBLEDevice::getServer(); }// getServer + +/** + * @brief Checks if the service has been started. + * @return True if the service has been started. + */ +bool NimBLEService::isStarted() { + return m_pSvcDef != nullptr; +} + + #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */ diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEService.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEService.h index 21ec1af70..73cbd87be 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEService.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEService.h @@ -44,7 +44,7 @@ public: uint16_t getHandle(); std::string toString(); void dump(); - + bool isStarted(); bool start(); NimBLECharacteristic* createCharacteristic(const char* uuid, diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEUtils.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEUtils.cpp index 60ea541f2..06e649c09 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEUtils.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEUtils.cpp @@ -16,45 +16,6 @@ static const char* LOG_TAG = "NimBLEUtils"; - -/** - * @brief A function for checking validity of connection parameters. - * @param [in] params A pointer to the structure containing the parameters to check. - * @return valid == 0 or error code. - */ -int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) { - /* Check connection interval min */ - if ((params->itvl_min < BLE_HCI_CONN_ITVL_MIN) || - (params->itvl_min > BLE_HCI_CONN_ITVL_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - /* Check connection interval max */ - if ((params->itvl_max < BLE_HCI_CONN_ITVL_MIN) || - (params->itvl_max > BLE_HCI_CONN_ITVL_MAX) || - (params->itvl_max < params->itvl_min)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check connection latency */ - if (params->latency > BLE_HCI_CONN_LATENCY_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check supervision timeout */ - if ((params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || - (params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check connection event length */ - if (params->min_ce_len > params->max_ce_len) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - return 0; -} - - /** * @brief Converts a return code from the NimBLE stack to a text string. * @param [in] rc The return code to convert. diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEUtils.h b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEUtils.h index 006d9352f..57d22a0aa 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEUtils.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEUtils.h @@ -43,7 +43,6 @@ public: static char* buildHexData(uint8_t* target, const uint8_t* source, uint8_t length); static const char* advTypeToString(uint8_t advType); static const char* returnCodeToString(int rc); - static int checkConnParams(ble_gap_conn_params* params); }; diff --git a/lib/libesp32_div/esp-nimble-cpp/src/nimconfig.h b/lib/libesp32_div/esp-nimble-cpp/src/nimconfig.h index 9c1903123..d96e37cf7 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/nimconfig.h +++ b/lib/libesp32_div/esp-nimble-cpp/src/nimconfig.h @@ -32,6 +32,18 @@ # endif #endif +#if CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED && !defined NDEBUG +void nimble_cpp_assert(const char *file, unsigned line) __attribute((weak, noreturn)); +# define NIMBLE_ATT_VAL_FILE (__builtin_strrchr(__FILE__, '/') ? \ + __builtin_strrchr (__FILE__, '/') + 1 : __FILE__) +# define NIMBLE_CPP_DEBUG_ASSERT(cond) \ + if (!(cond)) { \ + nimble_cpp_assert(NIMBLE_ATT_VAL_FILE, __LINE__); \ + } +#else +# define NIMBLE_CPP_DEBUG_ASSERT(cond) (void(0)) +#endif + #endif /* CONFIG_BT_ENABLED */ #ifdef _DOXYGEN_ diff --git a/tasmota/include/xsns_62_esp32_mi.h b/tasmota/include/xsns_62_esp32_mi.h index 9995b2ff1..27b4ad231 100644 --- a/tasmota/include/xsns_62_esp32_mi.h +++ b/tasmota/include/xsns_62_esp32_mi.h @@ -198,6 +198,7 @@ struct { uint32_t runningScan:1; uint32_t updateScan:1; uint32_t deleteScanTask:1; + uint32_t IRKinCfg:1; uint32_t canConnect:1; @@ -401,7 +402,7 @@ const char kMI32DeviceType[] PROGMEM = {"Flora|MJ_HT_V1|LYWSD02|LYWSD03|CGG1|CGD const char kMI32_ConnErrorMsg[] PROGMEM = "no Error|could not connect|did disconnect|got no service|got no characteristic|can not read|can not notify|can not write|did not write|notify time out"; -const char kMI32_BLEInfoMsg[] PROGMEM = "Scan ended|Got Notification|Did connect|Did disconnect|Still connected|Start passive scanning|Start active scanning|Server characteristic set|Server advertisement set|Server scan response set|Server client did connect|Server client did disconnect"; +const char kMI32_BLEInfoMsg[] PROGMEM = "Scan ended|Got Notification|Did connect|Did disconnect|Still connected|Start passive scanning|Start active scanning|Server characteristic set|Server advertisement set|Server scan response set|Server client did connect|Server client did disconnect| Server client did authenticate"; const char kMI32_ButtonMsg[] PROGMEM = "Single|Double|Hold"; //mapping: in Tasmota: 1,2,3 ; for HomeKit and Xiaomi 0,1,2 /*********************************************************************************************\ @@ -444,6 +445,7 @@ BLE_OP_ON_SUBSCRIBE_TO_NOTIFICATIONS_AND_INDICATIONS, BLE_OP_ON_CONNECT, BLE_OP_ON_DISCONNECT, BLE_OP_ON_STATUS, +BLE_OP_ON_AUTHENTICATED }; enum MI32_ConnErrorMsg { @@ -471,7 +473,8 @@ enum MI32_BLEInfoMsg { MI32_SERV_ADVERTISEMENT_ADDED, MI32_SERV_SCANRESPONSE_ADDED, MI32_SERV_CLIENT_CONNECTED, - MI32_SERV_CLIENT_DISCONNECTED + MI32_SERV_CLIENT_DISCONNECTED, + MI32_SERV_CLIENT_AUTHENTICATED }; /*********************************************************************************************\ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino index b836b7c3b..6db4ec644 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino @@ -208,6 +208,35 @@ extern "C" { be_raisef(vm, "ble_error", "BLE: could not add MAC to watch list"); } + // helper function + NimBLEConnInfo be_BLE_get_ConnInfo(NimBLEClient *device); + NimBLEConnInfo be_BLE_get_ConnInfo(NimBLEClient *device){ + if(!device){ + return NimBLEDevice::getServer()->getPeerInfo(0); + } else { + return NimBLEDevice::getClientList()->front()->getConnInfo(); + } + } + + // from esp-nimble/ble_sm.c + int ble_sm_read_bond(uint16_t conn_handle, struct ble_store_value_sec *out_bond) + { + struct ble_store_key_sec key_sec; + struct ble_gap_conn_desc desc; + int rc; + + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc != 0) { + return rc; + } + + memset(&key_sec, 0, sizeof key_sec); + key_sec.peer_addr = desc.peer_id_addr; + + rc = ble_store_read_peer_sec(&key_sec, out_bond); + return rc; + } + // BLE.info(void) -> map int32_t be_BLE_info(struct bvm *vm); int32_t be_BLE_info(struct bvm *vm) { @@ -225,26 +254,43 @@ extern "C" { #else be_map_insert_int(vm, "version", 4); #endif -#ifdef CONFIG_BT_NIMBLE_PERSIST +// #ifdef CONFIG_BT_NIMBLE_PERSIST be_map_insert_int(vm, "bonds", NimBLEDevice::getNumBonds()); -#else - be_map_insert_nil(vm, "bonds"); -#endif - if(MI32.mode.connected == 1){ - be_pushstring(vm, "connection"); - be_newobject(vm, "map"); - auto _info = NimBLEDevice::getClientList()->front()->getConnInfo(); - be_map_insert_str(vm, "peer_addr", _info.getAddress().toString().c_str()); - be_map_insert_int(vm, "RSSI", NimBLEDevice::getClientList()->front()->getRssi()); - be_map_insert_int(vm, "MTU", _info.getMTU()); - be_map_insert_bool(vm, "bonded", _info.isBonded()); - be_map_insert_bool(vm, "master", _info.isMaster()); - be_map_insert_bool(vm, "encrypted", _info.isEncrypted()); - be_map_insert_bool(vm, "authenticated", _info.isAuthenticated()); +// #else +// be_map_insert_nil(vm, "bonds"); +// #endif + if(MI32.mode.connected == 1 || MI32.ServerTask != nullptr){ + NimBLEClient* _device = nullptr; + if(MI32.mode.connected == 1){ + _device = NimBLEDevice::getClientList()->front(); + } + NimBLEConnInfo _info = be_BLE_get_ConnInfo(_device); + + be_pushstring(vm, "connection"); + be_newobject(vm, "map"); + + be_map_insert_str(vm, "peer_addr", _info.getAddress().toString().c_str()); + be_map_insert_str(vm, "peerID_addr", _info.getIdAddress().toString().c_str()); + if(_device != nullptr) be_map_insert_int(vm, "RSSI", _device->getRssi()); // ESP32 is client + be_map_insert_int(vm, "MTU", _info.getMTU()); + be_map_insert_bool(vm, "bonded", _info.isBonded()); + be_map_insert_bool(vm, "master", _info.isMaster()); + be_map_insert_bool(vm, "encrypted", _info.isEncrypted()); + be_map_insert_bool(vm, "authenticated", _info.isAuthenticated()); + if(_device == nullptr) be_map_insert_str(vm, "name", NimBLEDevice::getServer()->getPeerName(_info).c_str()); // ESP32 is server + + ble_store_value_sec value_sec; + ble_sm_read_bond(_info.getConnHandle(), &value_sec); + if(value_sec.irk_present == 1){ + char IRK[33]; + ToHex_P(value_sec.irk,16,IRK,33); + be_map_insert_str(vm, "IRK",IRK ); + } + + be_pop(vm, 1); + be_data_insert(vm, -3); + be_pop(vm, 2); - be_pop(vm, 1); - be_data_insert(vm, -3); - be_pop(vm, 2); } be_pop(vm, 1); @@ -271,6 +317,9 @@ be_BLE_op: 3 subscribe 4 unsubscribe - maybe later 5 disconnect +6 discover services +7 discover characteristics + 11 read once, then disconnect 12 write once, then disconnect @@ -294,6 +343,7 @@ __response 227 onConnect 228 onDisconnect 229 onStatus +230 onAuthenticated BLE.conn_cb(cb,buffer) diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino index c894b8796..b336ec17c 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino @@ -87,7 +87,7 @@ class MI32SensorCallback : public NimBLEClientCallbacks { MI32.infoMsg = MI32_DID_CONNECT; MI32.mode.willConnect = 0; MI32.mode.connected = 1; - pclient->updateConnParams(8,11,0,1000); + pclient->updateConnParams(8,16,0,1000); } void onDisconnect(NimBLEClient* pclient, int reason) { MI32.mode.connected = 0; @@ -186,6 +186,19 @@ class MI32ServerCallbacks: public NimBLEServerCallbacks { NimBLEDevice::startAdvertising(); #endif }; + void onAuthenticationComplete(const NimBLEConnInfo& connInfo) { + struct{ + BLERingBufferItem_t header; + uint8_t buffer[sizeof(ble_store_value_sec)]; + } item; + item.header.length = sizeof(ble_store_value_sec); + item.header.type = BLE_OP_ON_AUTHENTICATED; + ble_store_value_sec value_sec; + ble_sm_read_bond(connInfo.getConnHandle(), &value_sec); + memcpy(item.buffer,(uint8_t*)&value_sec,sizeof(ble_store_value_sec)); + xRingbufferSend(BLERingBufferQueue, (const void*)&item, sizeof(BLERingBufferItem_t), pdMS_TO_TICKS(1)); + MI32.infoMsg = MI32_SERV_CLIENT_AUTHENTICATED; + } }; class MI32CharacteristicCallbacks: public NimBLECharacteristicCallbacks { @@ -691,6 +704,12 @@ void MI32Init(void) { #endif const std::string name(TasmotaGlobal.hostname); NimBLEDevice::init(name); + #ifdef CONFIG_BT_NIMBLE_NVS_PERSIST + NimBLEDevice::setSecurityAuth(true, true, true); + #else + NimBLEDevice::setSecurityAuth(false, true, true); + #endif + AddLog(LOG_LEVEL_INFO,PSTR("M32: Init BLE device: %s"),TasmotaGlobal.hostname); MI32.mode.init = 1; MI32.mode.readyForNextConnJob = 1; @@ -947,6 +966,9 @@ void MI32loadCfg(){ MI32HexStringToBytes(_pidStr,_pid); uint16_t _pid16 = _pid[0]*256 + _pid[1]; _numberOfDevices = MIBLEgetSensorSlot(_mac,_pid16,0); + if (MIBLEsensors[_numberOfDevices].PID == 0) { // no Xiaomi sensor + MI32.option.handleEveryDevice = 1; // if in config, we assume to handle it + } _error = false; } } @@ -958,6 +980,9 @@ void MI32loadCfg(){ uint8_t *_key = (uint8_t*) malloc(16); MI32HexStringToBytes(_keyStr,_key); MIBLEsensors[_numberOfDevices].key = _key; + if (MIBLEsensors[_numberOfDevices].PID == 0) { // no Xiaomi sensor + MI32.mode.IRKinCfg = 1; // key is treated as IRK for RPA + } } else{ _error = true; @@ -1239,12 +1264,6 @@ bool MI32StartConnectionTask(){ void MI32ConnectionTask(void *pvParameters){ #if !defined(CONFIG_IDF_TARGET_ESP32C3) || !defined(CONFIG_IDF_TARGET_ESP32C6) //needs more testing ... // NimBLEDevice::setOwnAddrType(BLE_OWN_ADDR_RANDOM,false); //seems to be important for i.e. xbox controller, hopefully not breaking other things -#ifdef CONFIG_BT_NIMBLE_NVS_PERSIST - NimBLEDevice::setSecurityAuth(true, true, true); -#else - NimBLEDevice::setSecurityAuth(false, true, true); -#endif - #endif //CONFIG_IDF_TARGET_ESP32C3 MI32.conCtx->error = MI32_CONN_NO_ERROR; if (MI32ConnectActiveSensor()){ @@ -2049,11 +2068,33 @@ void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int RSSI) { } } +uint16_t MI32checkRPA(uint8_t *addr) { + br_aes_small_cbcenc_keys cbc_ctx; + size_t data_len = 16; + int idx = -1; + for (auto _sensor : MIBLEsensors) { + idx += 1; + if (_sensor.PID != 0) continue; + if (_sensor.key == nullptr) continue; + uint8_t iv[16] = {0}; + uint8_t data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,addr[0],addr[1],addr[2]}; + br_aes_small_cbcenc_init(&cbc_ctx, _sensor.key, 16); + br_aes_small_cbcenc_run( &cbc_ctx, iv, data, data_len ); + if(data[13] == addr[3] && data[14] == addr[4] && data[15] == addr[5]) { + MIBLEsensors[idx].lastTime = Rtc.local_time; + return idx; + } + } + return 0xff; +} + void MI32HandleEveryDevice(NimBLEAdvertisedDevice* advertisedDevice, uint8_t addr[6], int RSSI) { - if(advertisedDevice->getAddressType() != BLE_ADDR_PUBLIC) { - return; - } - uint16_t _slot = MIBLEgetSensorSlot(addr, 0, 0); + + uint16_t _slot; + if (advertisedDevice->getAddressType() == BLE_ADDR_PUBLIC) { _slot = MIBLEgetSensorSlot(addr, 0, 0);} + else if (advertisedDevice->getAddress().isRpa() && MI32.mode.IRKinCfg == 1) { _slot = MI32checkRPA(addr);} + else {return;} + if(_slot==0xff) { return; } From 4948b70acda72ac0b907f85f6160787851e53e96 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:44:05 +0200 Subject: [PATCH 005/205] Update changelogs Add DALI short address and group support --- CHANGELOG.md | 13 +- RELEASENOTES.md | 3 + tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 434 ++++++++++++++----- 3 files changed, 337 insertions(+), 113 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1fc61941..ebdf907ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,13 @@ All notable changes to this project will be documented in this file. ## [14.3.0.1] ### Added +- BLE track devices with RPA (#22300) +- DALI support for short addresses and groups ### Breaking Changed ### Changed +- ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 (#22299) ### Fixed @@ -30,11 +33,11 @@ All notable changes to this project will be documented in this file. - Command ``DaliSend
|,`` to send command (address+256 is repeat) on DALI bus - Command ``DaliQuery
|,`` to send command (address+256 is repeat) on DALI bus and wait up to DALI_TIMEOUT ms for response - Berry Serial `config` to change parity on-the-fly for RS-485 (#22285) -- Misubishi Electric HVAC Heat/Dry/Cool Auto operation mode (#22216) -- Misubishi Electric HVAC Bridge to HomeBridge/Homekit locally (#22236) -- Misubishi Electric HVAC Air Direction Control (#22241) -- Misubishi Electric HVAC prohibit function (#22269) -- Misubishi Electric HVAC compressor map and operation power and energy (#22290) +- Mitsubishi Electric HVAC Heat/Dry/Cool Auto operation mode (#22216) +- Mitsubishi Electric HVAC Bridge to HomeBridge/Homekit locally (#22236) +- Mitsubishi Electric HVAC Air Direction Control (#22241) +- Mitsubishi Electric HVAC prohibit function (#22269) +- Mitsubishi Electric HVAC compressor map and operation power and energy (#22290) ### Changed - ESP32 platform update from 2024.09.10 to 2024.09.30 and Framework (Arduino Core) from v3.0.5 to v3.1.0.240926 (#22203) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 17026f8f5..61b6aab1a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -116,10 +116,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ## Changelog v14.3.0.1 ### Added +- DALI support for short addresses and groups +- BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) ### Breaking Changed ### Changed +- ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 [#22299](https://github.com/arendst/Tasmota/issues/22299) ### Fixed diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index c11938e3d..1253fc73e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -19,6 +19,11 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.1.0.7 20241017 update - Add command `DaliCommission 1|2` assigning short addresses + - Add command `DaliTarget 0, 1..64, 101..116` to select light control address + - Add command `DaliGroup1..16 +|-` to add/remove devices from group + - Extend commands `DaliPower` and `DaliDimmer` with index to control short address or group + - Remove non-functional MQTT interface 0.1.0.6 20241014 update - Fix received light command loop - Add send collision detection 0.1.0.5 20241014 update - Add command `DaliSend [repeat]
,` @@ -43,6 +48,29 @@ /*********************************************************************************************\ * DALI support for Tasmota + * + * Available commands: + * = 0..255 or 0x00..0xFF + 256/0x100 for optional repeat (send twice) + * = 0..255 or 0x00..0xFF - Both decimal and hexadecimal is supported + * = 0 - DALI default + * = 1..64 - DALI short address + 1 + * = 101..116 - DALI group + 101 + * DaliSend , - Execute DALI code and do not expect a DALI backward frame + * DaliQuery , - Execute DALI code and report result (DALI backward frame) + * DaliCommission 1|2 - Reset (0) or (1)/and commission device short addresses + * DaliGroup<1..16> [+]|-,... - Add(+) or Remove(-) devices to/from group + * DaliPower|| 0..254 - Control power (0 = Off, 1 = Last dimmer, 2 = Toggle, 3..254 = absolute light brightness) + * DaliDimmer|| 0..100 - Control dimmer (0 = Off, 1..100 = precentage of brightness) + * DaliWeb 0|1 - Enable Tasmota light control for DaliTarget device + * DaliTarget || - Set Tasmota light control device (0, 1..64, 101..116) + * + * Address type Address byte + * ------------------ -------------------- + * Broadcast address 1111111S + * 64 short address 0AAAAAAS + * 16 group address 100AAAAS + * Special command 101CCCC1 to 110CCCC1 + * A = Address bit, S = 0 Direct Arc Power control, S = 1 Command, C = Special command \*********************************************************************************************/ #define XDRV_75 75 @@ -71,18 +99,18 @@ #define D_PRFX_DALI "Dali" const char kDALICommands[] PROGMEM = D_PRFX_DALI "|" // Prefix - "|" D_CMND_POWER + "|" D_CMND_POWER "|" D_CMND_DIMMER "|Target" #ifdef USE_LIGHT "|Web" #endif // USE_LIGHT - "|" D_CMND_DIMMER "|Send|Query" ; + "|Send|Query|Commission|Group"; void (* const DALICommand[])(void) PROGMEM = { - &CmndDali, &CmndDaliPower, + &CmndDali, &CmndDaliPower, &CmndDaliDimmer, &CmndDaliTarget, #ifdef USE_LIGHT &CmndDaliWeb, #endif // USE_LIGHT - &CmndDaliDimmer, &CmndDaliSend, &CmndDaliQuery }; + &CmndDaliSend, &CmndDaliQuery, &CmndDaliCommission, &CmndDaliGroup }; struct DALI { uint32_t bit_time; @@ -92,6 +120,7 @@ struct DALI { uint8_t address; uint8_t command; uint8_t dimmer; + uint8_t target; bool power; bool available; bool response; @@ -102,6 +131,35 @@ struct DALI { * DALI low level \*********************************************************************************************/ +uint32_t DaliTarget2Address(uint32_t target) { + // 1..64 = Short address + // 101..116 = Group address + // Others = Broadcast + if ((target >= 1) && (target <= 64)) { // 1 .. 64 + target -= 1; // Short address + target <<= 1; + } + else if ((target >= 101) && (target <= 116)) { // 101 .. 116 + target -= 101; + target <<= 1; + target |= 0x80; // Group address + } + else { // Others + target = DALI_BROADCAST_DP; // Broadcast address + } + return target &0xFE; // Direct Arc Power Control command +} +/* +uint32_t DaliAddress2Target(uint32_t adr) { + if (adr >= 254) { // 0b1111111S + return 0; // Broadcast address (0) + } + else if ((adr >= 128) && (adr <= 159)) { // 0b1000000S .. 0b1001111S + return (adr >> 1) +101; // Group address (101 .. 116) + } + return (adr >> 1) +1; // 0b0000000S .. 0b0111111S Short address (1 .. 64) +} +*/ void DaliEnableRxInterrupt(void) { Dali->available = false; attachInterrupt(Dali->pin_rx, DaliReceiveData, FALLING); @@ -243,7 +301,7 @@ void DaliSendData(uint32_t adr, uint32_t cmd) { Dali->address = adr; Dali->command = cmd; - if (DALI_BROADCAST_DP == adr) { + if (DaliTarget2Address(Dali->target) == adr) { repeat = true; Dali->power = (cmd); // State if (Dali->power) { @@ -263,6 +321,10 @@ void DaliSendData(uint32_t adr, uint32_t cmd) { } } +#ifdef DALI_DEBUG + AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: SendData Repeat %d, Adr 0x%02X, Cmd 0x%02x"), repeat, adr, cmd); +#endif // DALI_DEBUG + uint16_t send_dali_data = adr << 8 | cmd; DaliDisableRxInterrupt(); @@ -289,13 +351,164 @@ int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout) { result = Dali->received_dali_data; } Dali->response = false; + +#ifdef DALI_DEBUG + AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: SendWaitResponse result %d = 0x%04X"), result, result); +#endif // DALI_DEBUG + return result; } -void DaliPower(uint32_t val) { - DaliSendData(DALI_BROADCAST_DP, val); +/*********************************************************************************************\ + * DALI commissioning short addresses + * + * Courtesy of https://github.com/qqqlab/DALI-Lighting-Interface +\*********************************************************************************************/ + +// Query commands - Send as second byte +#define DALI_QUERY_STATUS 0x0090 // 144 - Returns "STATUS INFORMATION" + +// Special commands - Send as first byte +#define DALI_TERMINATE 0x00A1 // 256 - Releases the INITIALISE state. +#define DALI_INITIALISE 0x01A5 // 258 REPEAT - Sets the slave to the INITIALISE status for15 minutes. Commands 259 to 270 are enabled only for a slave in this status. +#define DALI_RANDOMISE 0x01A7 // 259 REPEAT - Generates a random address. +#define DALI_COMPARE 0x00A9 // 260 - Is the random address smaller or equal to the search address? +#define DALI_WITHDRAW 0x00AB // 261 - Excludes slaves for which the random address and search address match from the Compare process. +#define DALI_SEARCHADDRH 0x00B1 // 264 - Specifies the higher 8 bits of the search address. +#define DALI_SEARCHADDRM 0x00B3 // 265 - Specifies the middle 8 bits of the search address. +#define DALI_SEARCHADDRL 0x00B5 // 266 - Specifies the lower 8 bits of the search address. +#define DALI_PROGRAM_SHORT_ADDRESS 0x00B7 // 267 - The slave shall store the received 6-bit address (AAA AAA) as a short address if it is selected. + +void DaliSetSearchAddress(uint32_t adr) { + // Set search address + DaliSendData(DALI_SEARCHADDRH, adr>>16); + DaliSendData(DALI_SEARCHADDRM, adr>>8); + DaliSendData(DALI_SEARCHADDRL, adr); } +void DaliSetSearchAddressDifference(uint32_t adr_new, uint32_t adr_current) { + // Set search address, but set only changed bytes (takes less time) + if ( (uint8_t)(adr_new>>16) != (uint8_t)(adr_current>>16) ) DaliSendData(DALI_SEARCHADDRH, adr_new>>16); + if ( (uint8_t)(adr_new>>8) != (uint8_t)(adr_current>>8) ) DaliSendData(DALI_SEARCHADDRM, adr_new>>8); + if ( (uint8_t)(adr_new) != (uint8_t)(adr_current) ) DaliSendData(DALI_SEARCHADDRL, adr_new); +} + +bool DaliCompare() { + // Is the random address smaller or equal to the search address? + // As more than one device can reply, the reply gets garbled + uint8_t retry = 2; + while (retry > 0) { + // Compare is true if we received any activity on the bus as reply. + // Sometimes the reply is not registered... so only accept retry times 'no reply' as a real false compare + int rv = DaliSendWaitResponse(DALI_COMPARE, 0x00); + if (rv == 0xFF) return true; // Yes reply + retry--; + } + return false; +} + +uint32_t DaliFindAddress(void) { + // Find addr with binary search + uint32_t adr = 0x800000; + uint32_t addsub = 0x400000; + uint32_t adr_last = adr; + DaliSetSearchAddress(adr); + + while (addsub) { + DaliSetSearchAddressDifference(adr, adr_last); + adr_last = adr; + if (DaliCompare()) { // Returns true if searchadr > adr + adr -= addsub; + } else { + adr += addsub; + } + addsub >>= 1; + } + DaliSetSearchAddressDifference(adr, adr_last); + adr_last = adr; + if (!DaliCompare()) { + adr++; + DaliSetSearchAddressDifference(adr, adr_last); + } + return adr; +} + +void DaliProgramShortAddress(uint8_t shortadr) { + // The slave shall store the received 6-bit address (AAAAAA) as a short address if it is selected. + DaliSendData(DALI_PROGRAM_SHORT_ADDRESS, (shortadr << 1) | 0x01); + + AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Set short address %d"), shortadr +1); +} + +uint32_t DaliCommission(uint8_t init_arg) { + // init_arg=11111111 : all without short address + // init_arg=00000000 : all + // init_arg=0AAAAAA1 : only for this shortadr + // returns number of new short addresses assigned + DaliSendData(DALI_BROADCAST_DP, 0); // Turn all OFF + delay(100); // Need 100ms pause before starting commissioning + + uint8_t arr[64]; + uint32_t sa; + for (sa = 0; sa < 64; sa++) { + arr[sa] = 0; + } + + // Start commissioning + DaliSendData(DALI_INITIALISE, init_arg); + DaliSendData(DALI_RANDOMISE, 0x00); + delay(100); // Need 100ms pause after RANDOMISE + + // Find used short addresses (run always, seems to work better than without...) + for (sa = 0; sa < 64; sa++) { + int rv = DaliSendWaitResponse(sa << 1 | 1, DALI_QUERY_STATUS); + if (rv >= 0) { + if (init_arg != 0b00000000) { + arr[sa] = 1; // Remove address from list if not in "all" mode + } + } + } + + uint32_t cnt = 0; + while (true) { // Find random addresses and assign unused short addresses + uint32_t adr = DaliFindAddress(); + if (adr > 0xffffff) { break; } // No more random addresses found -> exit + for (sa = 0; sa < 64; sa++) { // Find first unused short address + if (0 == arr[sa]) { break; } + } + if( sa >= 64) { break; } // All 64 short addresses assigned -> exit + arr[sa] = 1; // Mark short address as used + cnt++; + + DaliProgramShortAddress(sa); // Assign short address + DaliSendData(DALI_WITHDRAW, 0x00); // Remove the device from the search + + delay(1); + OsWatchLoop(); + } + + DaliSendData(DALI_TERMINATE, 0x00); // Terminate the DALI_INITIALISE command + + for (sa = 0; sa < cnt; sa++) { + AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Flash short address %d"), sa +1); + + DaliSendData(sa << 1, 200); // Flash assigned lights + delay(1000); + OsWatchLoop(); + DaliSendData(sa << 1, 0); + } + + return cnt; +} + +/*********************************************************************************************\ + * DALI group management +\*********************************************************************************************/ + +// Configuration commands - Send as second byte +#define DALI_ADD_TO_GROUP0 0x0060 // 96 - Adds the slave to Group XXXX. +#define DALI_REMOVE_FROM_GROUP0 0x0070 // 112 - Deletes the slave from Group XXXX. + /***********************************************************/ void ResponseAppendDali(void) { @@ -318,7 +531,7 @@ void DaliInput(void) { #ifdef USE_LIGHT bool show_response = true; - if (DALI_BROADCAST_DP == Dali->address) { + if (DaliTarget2Address(Dali->target) == Dali->address) { uint8_t dimmer_old = changeUIntScale(Dali->dimmer, 0, 254, 0, 100); uint8_t power_old = Dali->power; Dali->power = (Dali->command); // State @@ -345,7 +558,7 @@ void DaliInput(void) { MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_PRFX_DALI)); } #else - if (DALI_BROADCAST_DP == Dali->address) { + if (DaliTarget2Address(Dali->target) == Dali->address) { Dali->power = (Dali->command); // State if (Dali->power) { Dali->dimmer = Dali->command; // Value @@ -366,7 +579,7 @@ bool DaliSetChannels(void) { } else { uint8_t value = ((uint8_t*)XdrvMailbox.data)[0]; if (255 == value) { value = 254; } // Max Dali value - DaliPower(value); + DaliSendData(DaliTarget2Address(Dali->target), value); } } return true; @@ -411,84 +624,6 @@ bool DaliInit(void) { #endif // USE_LIGHT } -/*********************************************************************************************\ - * Experimental - Not functioning -\*********************************************************************************************/ - -bool DaliMqtt(void) { -/* - XdrvMailbox.topic = topic; - XdrvMailbox.index = strlen(topic); - XdrvMailbox.data = (char*)data; - XdrvMailbox.data_len = data_len; - - This won't work as there is currently no subscribe done -*/ - char stopic[TOPSZ]; - strncpy(stopic, XdrvMailbox.topic, TOPSZ); - XdrvMailbox.topic[TOPSZ - 1] = 0; - - char *items[10]; - char *p = stopic; - int cnt = 0; - do { - items[cnt] = strtok(p, "/"); - cnt++; - p = nullptr; - } while (items[cnt - 1]); - cnt--; // represents the number of items - - AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Cnt %d, Topic '%s', Payload '%s'"), cnt, XdrvMailbox.topic, XdrvMailbox.data); - - if (cnt < 3) { // not for us? - AddLog(LOG_LEVEL_INFO, PSTR("DLI: Cnt %d < 3"), cnt); - return false; - } - - int DALIindex = 0; - int ADRindex = 0; - int CMDindex = 0; - uint8_t DALIaddr = DALI_BROADCAST_DP; - - if (strcasecmp_P(items[cnt - 3], PSTR(DALI_TOPIC)) != 0) { // dali - // cmnd - if (strcasecmp_P(items[cnt - 2], PSTR(DALI_TOPIC)) != 0) { // dali - // device - return false; // not for us - } else { - // cmnd/dali/percent - DALIindex = cnt - 2; - CMDindex = cnt - 1; - } - } else { - // dali/percent/2 20 - DALIindex = cnt - 3; - CMDindex = cnt - 2; - ADRindex = cnt - 1; - DALIaddr = ((int)CharToFloat(items[ADRindex])) << 1; - } - - uint8_t level; - uint8_t value = (uint8_t)CharToFloat(XdrvMailbox.data); - if (strcasecmp_P(items[CMDindex], PSTR("percent")) == 0) { - // dali/percent/ - float percent = (float)(254 * value * 0.01); - level = (uint8_t)percent; - } - else if (strcasecmp_P(items[CMDindex], PSTR("level")) == 0) { - level = value; - } - else { - AddLog(LOG_LEVEL_INFO,PSTR("DLI: Command not recognized: %s"), items[CMDindex]); - return false; // not for us - } - - AddLog(LOG_LEVEL_INFO,PSTR("DLI: Dali value %d on address %d"), value, DALIaddr); - DaliSendData(DALIaddr, level); - - return true; -} - /*********************************************************************************************\ * Commands \*********************************************************************************************/ @@ -548,37 +683,109 @@ void CmndDali(void) { ResponseDali(); } +void CmndDaliTarget(void) { + // DaliTarget - Set transmit target + // DaliTarget 0 - Set target to broadcast address + // DaliTarget 1..64 - Set target to short address + // DaliTarget 101..116 - Set target to group address + if (((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 64)) || + ((XdrvMailbox.payload >= 101) && (XdrvMailbox.payload <= 116)) || + (XdrvMailbox.payload == 0)) { + Dali->target = XdrvMailbox.payload; + } + ResponseCmndNumber(Dali->target); +} + void CmndDaliPower(void) { - // DaliPower 0 - Power off - // DaliPower 1 - Power on to last dimmer state - // DaliPower 2 - Toggle power off or last dimmer state - // DaliPower 3..254 - Equals DaliDimmer command - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 254)) { - if (XdrvMailbox.payload <= 2) { - if (2 == XdrvMailbox.payload) { - XdrvMailbox.payload = (Dali->power) ? 0 : 1; + // DaliPower 0 - Broadcast power off + // DaliPower 1 - Broadcast power on to last dimmer state + // DaliPower 2 - Broadcast toggle power off or last dimmer state + // DaliPower 3..254 - Broadcast equals DaliDimmer command + // DaliPower 0..254 - Broadcast control + // DaliPower0 0..254 - Broadcast control (= DaliPower) + // DaliPower1 0..254 - Short address 0 control + // DaliPower3 0..254 - Short address 2 control + if (((XdrvMailbox.index >= 0) && (XdrvMailbox.index <= 64)) || + ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116))) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 254)) { + if (XdrvMailbox.payload <= 2) { + if (2 == XdrvMailbox.payload) { + XdrvMailbox.payload = (Dali->power) ? 0 : 1; + } + if (1 == XdrvMailbox.payload) { + XdrvMailbox.payload = Dali->dimmer; + } } - if (1 == XdrvMailbox.payload) { - XdrvMailbox.payload = Dali->dimmer; + uint32_t DALIaddr = DALI_BROADCAST_DP; + if (XdrvMailbox.index >= 101) { + DALIaddr = ((XdrvMailbox.index -101) << 1) | 0x80; // Group address } + else if ((XdrvMailbox.index > 0) && XdrvMailbox.usridx) { + DALIaddr = (XdrvMailbox.index -1) << 1; // Short address + } + DaliSendData(DALIaddr, XdrvMailbox.payload); } - DaliPower(XdrvMailbox.payload); } ResponseDali(); } void CmndDaliDimmer(void) { - // DaliDimmer 0..100 - Set power off or dimmer state - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { - uint8_t dimmer = changeUIntScale(XdrvMailbox.payload, 0, 100, 0, 254); - DaliPower(dimmer); + // DaliDimmer 0..100 - Broadcast set power off or dimmer state + // DaliDimmer0 0..100 - Broadcast set power off or dimmer state + // DaliDimmer1 0..100 - Short address 0 set power off or dimmer state + // DaliDimmer3 0..100 - Short address 2 set power off or dimmer state + if (((XdrvMailbox.index >= 0) && (XdrvMailbox.index <= 64)) || + ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116))) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { + uint8_t dimmer = changeUIntScale(XdrvMailbox.payload, 0, 100, 0, 254); + uint32_t DALIaddr = DALI_BROADCAST_DP; + if (XdrvMailbox.index >= 101) { + DALIaddr = ((XdrvMailbox.index -101) << 1) | 0x80; // Group address + } + else if ((XdrvMailbox.index > 0) && XdrvMailbox.usridx) { + DALIaddr = (XdrvMailbox.index -1) << 1; // Short address + } + DaliSendData(DALIaddr, dimmer); + } } ResponseDali(); } +void CmndDaliGroup(void) { + // DaliGroup1 1,2 - Add device 1 and 2 to group 1 + // DaliGroup1 -1,2 - Remove device 1 and 2 to group 1 + if ((XdrvMailbox.index >= 1) && (XdrvMailbox.index <= 16)) { + if (XdrvMailbox.data_len) { + uint32_t command = DALI_ADD_TO_GROUP0; + if ('+' == XdrvMailbox.data[0]) { // Add devices + XdrvMailbox.data++; + XdrvMailbox.data_len--; + } + else if ('-' == XdrvMailbox.data[0]) { // Remove devices + command = DALI_REMOVE_FROM_GROUP0; + XdrvMailbox.data++; + XdrvMailbox.data_len--; + } + uint32_t argc = ArgC(); // Number of devices + if (argc) { + command |= (XdrvMailbox.index -1); + uint32_t sas[argc]; + ParseParameters(argc, sas); + for (uint32_t arg = 0; arg < argc; arg++) { + uint32_t sa = sas[arg] -1; + if (sa <= 63) { + DaliSendData(sa << 1 | 0x01, command); + } + } + ResponseCmndDone(); + } + } + } +} + void CmndDaliSend(void) { // Send command - // Setting bit 8 will repeat command twice + // Setting bit 8 will repeat command once // DaliSend 0x1a5,255 - DALI Initialise (send twice) uint32_t values[2] = { 0 }; uint32_t params = ParseParameters(2, values); @@ -590,7 +797,7 @@ void CmndDaliSend(void) { void CmndDaliQuery(void) { // Send command and return response or -1 (no response within DALI_TIMEOUT) - // Setting bit 8 will repeat command twice + // Setting bit 8 will repeat command once // DaliQuery 0xff,0x90 - DALI Query status // DaliQuery 0xff,144 - DALI Query status uint32_t values[2] = { 0 }; @@ -601,6 +808,20 @@ void CmndDaliQuery(void) { } } +void CmndDaliCommission(void) { + // Commission short addresses + // DaliCommission 1 - Reset and commission short addresses + // DaliCommission 2 - Commission unassigned short addresses + if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 2)) { + uint32_t init_arg = 0x00; // Commission all + if (2 == XdrvMailbox.payload) { + init_arg = 0xFF; // Commission all without short addresses + } + int result = DaliCommission(init_arg); + ResponseCmndNumber(result); + } +} + #ifdef USE_LIGHT void CmndDaliWeb(void) { // DaliWeb 0 - Disable GUI light controls @@ -639,9 +860,6 @@ bool Xdrv75(uint32_t function) { case FUNC_LOOP: DaliInput(); break; - case FUNC_MQTT_DATA: - result = DaliMqtt(); - break; #ifdef USE_LIGHT case FUNC_SET_CHANNELS: result = DaliSetChannels(); From a35b7a9f82b6c1bc71f90c507b340db99c78dfe1 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 17 Oct 2024 20:18:32 +0200 Subject: [PATCH 006/205] change MI32 env to latest needs of NimBLE lib --- platformio_tasmota_cenv_sample.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini index 3643e3d7c..8ba11666b 100644 --- a/platformio_tasmota_cenv_sample.ini +++ b/platformio_tasmota_cenv_sample.ini @@ -102,6 +102,7 @@ extends = env:tasmota32_base build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_BLUETOOTH -DUSE_MI_EXT_GUI + -DCONFIG_BT_NIMBLE_NVS_PERSIST=y -DOTA_URL='""' lib_extra_dirs = lib/libesp32, lib/libesp32_div, lib/lib_basic, lib/lib_i2c, lib/lib_div, lib/lib_ssl lib_ignore = Micro-RTSP @@ -112,6 +113,7 @@ board = esp32c3 build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_BLUETOOTH -DUSE_MI_EXT_GUI + -DCONFIG_BT_NIMBLE_NVS_PERSIST=y -DOTA_URL='""' lib_extra_dirs = lib/libesp32, lib/libesp32_div, lib/lib_basic, lib/lib_i2c, lib/lib_div, lib/lib_ssl lib_ignore = Micro-RTSP @@ -122,6 +124,7 @@ board = esp32s3-qio_qspi build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_BLUETOOTH -DUSE_MI_EXT_GUI + -DCONFIG_BT_NIMBLE_NVS_PERSIST=y -DOTA_URL='""' lib_extra_dirs = lib/libesp32, lib/libesp32_div, lib/lib_basic, lib/lib_i2c, lib/lib_div, lib/lib_ssl lib_ignore = Micro-RTSP @@ -132,6 +135,7 @@ board = esp32c6 build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_BLUETOOTH -DUSE_MI_EXT_GUI + -DCONFIG_BT_NIMBLE_NVS_PERSIST=y -DOTA_URL='""' ; *** Debug version used for PlatformIO Home Project Inspection From 5a204aea48d649aae6db28a94527760f819ea35a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 17 Oct 2024 21:29:37 +0200 Subject: [PATCH 007/205] Disabling midi for esp32 -> Compiler BUG --- .../ESP8266Audio/src/libtinysoundfont/tsf.h | 218 +++++++++++++----- 1 file changed, 156 insertions(+), 62 deletions(-) diff --git a/lib/lib_audio/ESP8266Audio/src/libtinysoundfont/tsf.h b/lib/lib_audio/ESP8266Audio/src/libtinysoundfont/tsf.h index 45d7b97a5..e40be9898 100644 --- a/lib/lib_audio/ESP8266Audio/src/libtinysoundfont/tsf.h +++ b/lib/lib_audio/ESP8266Audio/src/libtinysoundfont/tsf.h @@ -42,6 +42,16 @@ */ +// ESP32 as of 3.x has a compiler bug in this section, with the G++ generated assembly +// being illegal. There's nothing wrong with the code here, it just looks like an +// Xtensa backend issue. Until that's fixed, no MIDI for you! +///home/earle/Arduino/libraries/ESP8266Audio/src/libtinysoundfont/tsf.h: In function 'void tsf_channel_midi_control(tsf*, int, int, int)': +// /home/earle/Arduino/libraries/ESP8266Audio/src/libtinysoundfont/tsf.h:2101:1: error: insn does not satisfy its constraints: +// 2101 | } +// | ^ + +#if !defined(ESP32) + #ifndef TSF_INCLUDE_TSF_INL #define TSF_INCLUDE_TSF_INL @@ -190,7 +200,6 @@ TSFDEF void tsf_channel_set_bank(tsf* f, int channel, int bank); TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number); TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan); TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume); -TSFDEF void tsf_channel_set_volume_to_one(tsf* f, int channel); // solves a Compiler bug!! TODO: refactor after compiler fix!! TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel); TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range); TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning); @@ -603,11 +612,11 @@ struct tsf_voice { int playingPreset, playingKey, playingChannel; struct tsf_region* region; - double pitchInputTimecents, pitchOutputFactor; + double pitchRatio; double sourceSamplePosition; - fixed32p32 sourceSamplePositionF32P32; - float noteGainDB, panFactorLeft, panFactorRight; - unsigned int playIndex, loopStart, loopEnd; + fixed32p32 sourceSamplePositionF32P32, loopStartF32P32, loopEndF32P32, loopSizeF32P32, pitchRatioF32P32; + float noteGain, panFactorLeft, panFactorRight; + int playIndex, loopStart, loopEnd; struct tsf_voice_envelope ampenv, modenv; struct tsf_voice_lowpass lowpass; struct tsf_voice_lfo modlfo, viblfo; @@ -626,6 +635,14 @@ struct tsf_channels int channelNum, activeChannel; }; +// Math properties of tsf_timecents2Secs* (tc2s): +// # tc2s(a + b) = tc2s(a) * tc2s(b) +// # tc2s(a - b) = tc2s(a) / tc2s(b) +// # 1 / tc2s(a) = tc2s(-a) +// # The same applies to tsf_cents2Hertz and tsf_decibelsToGain +// Path properties of tsf_decibelsToGain (db2g) and tsf_gainToDecibels (g2db) +// # db2g(g2db(a)) = a +// # g2db(db2g(a)) = a static double tsf_timecents2Secsd(double timecents) { return TSF_POW(2.0, timecents / 1200.0); } static float tsf_timecents2Secsf(float timecents) { return TSF_POWF(2.0f, timecents / 1200.0f); } static float tsf_cents2Hertz(float cents) { return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); } @@ -1221,6 +1238,7 @@ static void tsf_voice_end(struct tsf_voice* v, float outSampleRate) { // Continue playing, but stop looping. v->loopEnd = v->loopStart; + v->loopSizeF32P32 = 0; } } @@ -1233,10 +1251,9 @@ static void tsf_voice_endquick(struct tsf_voice* v, float outSampleRate) static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate) { double note = v->playingKey + v->region->transpose + v->region->tune / 100.0; - double adjustedPitch = v->region->pitch_keycenter + (note - v->region->pitch_keycenter) * (v->region->pitch_keytrack / 100.0); - if (pitchShift) adjustedPitch += pitchShift; - v->pitchInputTimecents = adjustedPitch * 100.0; - v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate); + double adjustedPitch = (note - v->region->pitch_keycenter) * v->region->pitch_keytrack; + if (pitchShift) adjustedPitch += adjustedPitch * 100.0f; + v->pitchRatio = v->region->sample_rate * tsf_timecents2Secsd(adjustedPitch) / outSampleRate; } short tsf_read_short_cached(tsf *f, int pos) @@ -1304,10 +1321,10 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0; if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; - else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; + else pitchRatio = v->pitchRatio, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; - else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0; + else noteGain = v->noteGain, tmpModLfoToVolume = 0; while (numSamples) { @@ -1324,10 +1341,10 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i } if (dynamicPitchRatio) - pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor; + pitchRatio = v->pitchRatio * tsf_timecents2Secsd(v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch); if (dynamicGain) - noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume)); + noteGain = v->noteGain * tsf_decibelsToGain(v->modlfo.level * tmpModLfoToVolume); gainMono = noteGain * v->ampenv.level; @@ -1436,39 +1453,22 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc); TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume)); TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch)); - TSF_BOOL isLooping = (v->loopStart < v->loopEnd); - unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd; - //double tmpSampleEndDbl = (double)v->sampleEnd, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0; - //double tmpSourceSamplePosition = v->sourceSamplePosition; - fixed32p32 tmpSampleEndF32P32 = ((fixed32p32)(region->end)) << 32; - fixed32p32 tmpLoopEndF32P32 = ((fixed32p32)(tmpLoopEnd + 1)) << 32; + TSF_BOOL isLooping = (v->loopSizeF32P32 > 0); + fixed32p32 tmpSampleEndF32P32 = (fixed32p32)(region->end) << 32; fixed32p32 tmpSourceSamplePositionF32P32 = v->sourceSamplePositionF32P32; - struct tsf_voice_lowpass tmpLowpass = v->lowpass; - - TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc); - float tmpSampleRate = f->outSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc; TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch); - //double pitchRatio; - fixed32p32 pitchRatioF32P32; + fixed32p32 pitchRatioF32P32, tmpPitchRatioF32P32; float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch; TSF_BOOL dynamicGain = (region->modLfoToVolume != 0); - float noteGain, tmpModLfoToVolume; + float noteGain, tmpNoteGain, tmpModLfoToVolume; - if (dynamicLowpass) tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc; - else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0; + if (dynamicPitchRatio) tmpPitchRatioF32P32 = v->pitchRatioF32P32, pitchRatioF32P32 = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; + else pitchRatioF32P32 = v->pitchRatioF32P32, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; - if (dynamicPitchRatio) pitchRatioF32P32 = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; - else { - double pr = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor; - fixed32p32 adj = 1LL<<32; - pr *= adj; - pitchRatioF32P32 = (int64_t)pr, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; - } - - if (dynamicGain) noteGain = 0, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; - else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0; + if (dynamicGain) noteGain = 0, tmpNoteGain = v->noteGain, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; + else noteGain = v->noteGain, tmpModLfoToVolume = 0; while (numSamples) { @@ -1476,19 +1476,17 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples); numSamples -= blockSamples; - if (dynamicLowpass) - { - float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc; - tmpLowpass.active = (fres <= 13500.0f); - if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, tsf_cents2Hertz(fres) / tmpSampleRate); + if (dynamicPitchRatio) { + if (v->modlfo.level || v->viblfo.level || v->modenv.level) + pitchRatioF32P32 = tmpPitchRatioF32P32 * tsf_timecents2Secsd(v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch); + else + pitchRatioF32P32 = tmpPitchRatioF32P32; // If all levels are 0, just bypass conversion function } - if (dynamicPitchRatio) { - pitchRatioF32P32 = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor * (1LL<<32); - } - - if (dynamicGain) - noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume)); + if (dynamicGain) { + if (v->modlfo.level) noteGain = tmpNoteGain * tsf_decibelsToGain(v->modlfo.level * tmpModLfoToVolume); + else noteGain = tmpNoteGain; // If level is 0, just bypass conversion function + } gainMono = noteGain * v->ampenv.level; short gainMonoFP = gainMono * 32767; @@ -1501,7 +1499,7 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples); if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples); - while (blockSamples-- && tmpSourceSamplePositionF32P32 < tmpSampleEndF32P32) + while (blockSamples--) { unsigned int pos = (unsigned int)(tmpSourceSamplePositionF32P32>>32); if (pos == 0xffffffff) pos = 0; @@ -1513,8 +1511,14 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff // Next sample. tmpSourceSamplePositionF32P32 += pitchRatioF32P32; - if (tmpSourceSamplePositionF32P32 >= tmpLoopEndF32P32 && isLooping) - tmpSourceSamplePositionF32P32 -= (tmpLoopEndF32P32 - tmpLoopStart + (1LL<<32)); + + if (tmpSourceSamplePositionF32P32 >= v->loopEndF32P32) + { + if (isLooping) + tmpSourceSamplePositionF32P32 -= v->loopSizeF32P32; + else if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32) + break; + } } if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32 || v->ampenv.segment == TSF_SEGMENT_DONE) @@ -1525,7 +1529,6 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff } v->sourceSamplePositionF32P32 = tmpSourceSamplePositionF32P32; - if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass; } @@ -1720,13 +1723,14 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel) } voice = &f->voices[f->voiceNum - 4]; voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1; + voice[1].playIndex = voice[2].playIndex = voice[3].playIndex = -1; } voice->region = region; voice->playingPreset = preset_index; voice->playingKey = key; voice->playIndex = voicePlayIndex; - voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel); + voice->noteGain = vel * tsf_decibelsToGain(f->globalGainDB - region->attenuation); if (f->channels) { @@ -1742,7 +1746,6 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel) // Offset/end. voice->sourceSamplePosition = region->offset; - voice->sourceSamplePositionF32P32 = ((int64_t)region->offset)<< 32; // Loop. doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end); @@ -1767,6 +1770,86 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel) } } +/** + * Returns the generated playing index that can be used to identify all voices related to this note. + */ +TSFDEF int tsf_note_on_fast(tsf* f, int preset_index, int key, float vel) +{ + if (preset_index < 0 || preset_index >= f->presetNum) return -1; + if (!vel) { tsf_note_off(f, preset_index, key); return -1; } + if (f->presets[preset_index].regions == NULL) tsf_load_preset(f, f->hydra, preset_index); + + short midiVelocity = (short)(vel * 127); + struct tsf_region *region, *regionEnd; + + // Play all matching regions. + int voicePlayIndex = f->voicePlayIndex++; + for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++) + { + if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) continue; + + struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; + voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum; + if (region->group) + { + for (; v != vEnd; v++) + if (v->playingPreset == preset_index && v->region->group == region->group) tsf_voice_endquick(v, f->outSampleRate); + else if (v->playingPreset == -1 && !voice) voice = v; + } + else for (; v != vEnd; v++) if (v->playingPreset == -1) { voice = v; break; } + + if (!voice) + { + f->voiceNum += 4; + struct tsf_voice *saveVoice = f->voices; + f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice)); + if (!f->voices) { + f->voices = saveVoice; + printf("OOM, no room for new voice. Ignoring note_on\n"); + return -1; + } + voice = &f->voices[f->voiceNum - 4]; + voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1; + voice[1].playIndex = voice[2].playIndex = voice[3].playIndex = -1; + } + + voice->region = region; + voice->playingPreset = preset_index; + voice->playingKey = key; + voice->playIndex = voicePlayIndex; + voice->noteGain = vel * tsf_decibelsToGain(f->globalGainDB - region->attenuation); + + if (f->channels) + { + f->channels->setupVoice(f, voice); + } + else + { + tsf_voice_calcpitchratio(voice, 0, f->outSampleRate); + voice->pitchRatioF32P32 = voice->pitchRatio * (1LL << 32); + } + + // Offset/end. + voice->sourceSamplePositionF32P32 = ((int64_t)region->offset)<< 32; + + // Loop. + doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end); + voice->loopStartF32P32 = doLoop ? ((int64_t)region->loop_start + 1) << 32 : 0; + voice->loopEndF32P32 = doLoop ? ((int64_t)region->loop_end + 1) << 32 : 0; + voice->loopSizeF32P32 = doLoop ? voice->loopEndF32P32 - voice->loopStartF32P32 + (1LL << 32) : 0; + + // Setup envelopes. + tsf_voice_envelope_setup(&voice->ampenv, ®ion->ampenv, key, midiVelocity, TSF_TRUE, f->outSampleRate); + tsf_voice_envelope_setup(&voice->modenv, ®ion->modenv, key, midiVelocity, TSF_FALSE, f->outSampleRate); + + // Setup LFO filters. + tsf_voice_lfo_setup(&voice->modlfo, region->delayModLFO, region->freqModLFO, f->outSampleRate); + tsf_voice_lfo_setup(&voice->viblfo, region->delayVibLFO, region->freqVibLFO, f->outSampleRate); + } + + return voicePlayIndex; +} + TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel) { int preset_index = tsf_get_presetindex(f, bank, preset_number); @@ -1795,6 +1878,19 @@ TSFDEF void tsf_note_off(tsf* f, int preset_index, int key) } } +/** + * Stops all voices with the given playing index. If no key provided or if -1, fallbacks to tsf_note_off + */ +TSFDEF void tsf_note_off_fast(tsf* f, int preset_index, int key, int playIndex = -1) +{ + if (playIndex < 0) + tsf_note_off(f, preset_index, key); + else + for (struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; v != vEnd; v++) + if (v->playIndex == playIndex && v->playingPreset == preset_index && v->playingKey == key && v->ampenv.segment < TSF_SEGMENT_RELEASE) + tsf_voice_end(v, f->outSampleRate); +} + TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key) { int preset_index = tsf_get_presetindex(f, bank, preset_number); @@ -1874,7 +1970,7 @@ static void tsf_channel_setup_voice(tsf* f, struct tsf_voice* v) struct tsf_channel* c = &f->channels->channels[f->channels->activeChannel]; float newpan = v->region->pan + c->panOffset; v->playingChannel = f->channels->activeChannel; - v->noteGainDB += c->gainDB; + v->noteGain *= tsf_decibelsToGain(c->gainDB); tsf_voice_calcpitchratio(v, (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)), f->outSampleRate); if (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; } else if (newpan >= 0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; } @@ -1984,7 +2080,7 @@ TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume) if (gainDBChange == 0) return; for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++) if (v->playingChannel == channel && v->playingPreset != -1) - v->noteGainDB += gainDBChange; + v->noteGain *= tsf_decibelsToGain(gainDBChange); c->gainDB = gainDB; } @@ -2055,10 +2151,6 @@ TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel) tsf_voice_endquick(v, f->outSampleRate); } -TSFDEF void tsf_channel_set_volume_to_one(tsf* f, int channel){ - tsf_channel_set_volume(f, channel, 1.0f); -} - TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value) { struct tsf_channel* c = tsf_channel_init(f, channel); @@ -2084,7 +2176,7 @@ TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int co c->midiVolume = c->midiExpression = 16383; c->midiPan = 8192; c->bank = 0; - tsf_channel_set_volume_to_one(f, channel); + tsf_channel_set_volume(f, channel, 1.0f); tsf_channel_set_pan(f, channel, 0.5f); tsf_channel_set_pitchrange(f, channel, 2.0f); return; @@ -2149,3 +2241,5 @@ TSFDEF float tsf_channel_get_tuning(tsf* f, int channel) #endif #endif //TSF_IMPLEMENTATION + +#endif // ! ESP32 From fa7e0f938e18c174879cddb77c179637fdf87d5c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 17 Oct 2024 21:48:55 +0200 Subject: [PATCH 008/205] only disable midi for esp32 no code update Disable since esp32 compiler bug --- .../ESP8266Audio/src/libtinysoundfont/tsf.h | 206 ++++++------------ 1 file changed, 62 insertions(+), 144 deletions(-) diff --git a/lib/lib_audio/ESP8266Audio/src/libtinysoundfont/tsf.h b/lib/lib_audio/ESP8266Audio/src/libtinysoundfont/tsf.h index e40be9898..cdc1f6863 100644 --- a/lib/lib_audio/ESP8266Audio/src/libtinysoundfont/tsf.h +++ b/lib/lib_audio/ESP8266Audio/src/libtinysoundfont/tsf.h @@ -200,6 +200,7 @@ TSFDEF void tsf_channel_set_bank(tsf* f, int channel, int bank); TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number); TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan); TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume); +TSFDEF void tsf_channel_set_volume_to_one(tsf* f, int channel); // solves a Compiler bug!! TODO: refactor after compiler fix!! TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel); TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range); TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning); @@ -612,11 +613,11 @@ struct tsf_voice { int playingPreset, playingKey, playingChannel; struct tsf_region* region; - double pitchRatio; + double pitchInputTimecents, pitchOutputFactor; double sourceSamplePosition; - fixed32p32 sourceSamplePositionF32P32, loopStartF32P32, loopEndF32P32, loopSizeF32P32, pitchRatioF32P32; - float noteGain, panFactorLeft, panFactorRight; - int playIndex, loopStart, loopEnd; + fixed32p32 sourceSamplePositionF32P32; + float noteGainDB, panFactorLeft, panFactorRight; + unsigned int playIndex, loopStart, loopEnd; struct tsf_voice_envelope ampenv, modenv; struct tsf_voice_lowpass lowpass; struct tsf_voice_lfo modlfo, viblfo; @@ -635,14 +636,6 @@ struct tsf_channels int channelNum, activeChannel; }; -// Math properties of tsf_timecents2Secs* (tc2s): -// # tc2s(a + b) = tc2s(a) * tc2s(b) -// # tc2s(a - b) = tc2s(a) / tc2s(b) -// # 1 / tc2s(a) = tc2s(-a) -// # The same applies to tsf_cents2Hertz and tsf_decibelsToGain -// Path properties of tsf_decibelsToGain (db2g) and tsf_gainToDecibels (g2db) -// # db2g(g2db(a)) = a -// # g2db(db2g(a)) = a static double tsf_timecents2Secsd(double timecents) { return TSF_POW(2.0, timecents / 1200.0); } static float tsf_timecents2Secsf(float timecents) { return TSF_POWF(2.0f, timecents / 1200.0f); } static float tsf_cents2Hertz(float cents) { return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); } @@ -1238,7 +1231,6 @@ static void tsf_voice_end(struct tsf_voice* v, float outSampleRate) { // Continue playing, but stop looping. v->loopEnd = v->loopStart; - v->loopSizeF32P32 = 0; } } @@ -1251,9 +1243,10 @@ static void tsf_voice_endquick(struct tsf_voice* v, float outSampleRate) static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate) { double note = v->playingKey + v->region->transpose + v->region->tune / 100.0; - double adjustedPitch = (note - v->region->pitch_keycenter) * v->region->pitch_keytrack; - if (pitchShift) adjustedPitch += adjustedPitch * 100.0f; - v->pitchRatio = v->region->sample_rate * tsf_timecents2Secsd(adjustedPitch) / outSampleRate; + double adjustedPitch = v->region->pitch_keycenter + (note - v->region->pitch_keycenter) * (v->region->pitch_keytrack / 100.0); + if (pitchShift) adjustedPitch += pitchShift; + v->pitchInputTimecents = adjustedPitch * 100.0; + v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate); } short tsf_read_short_cached(tsf *f, int pos) @@ -1321,10 +1314,10 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0; if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; - else pitchRatio = v->pitchRatio, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; + else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; - else noteGain = v->noteGain, tmpModLfoToVolume = 0; + else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0; while (numSamples) { @@ -1341,10 +1334,10 @@ static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, i } if (dynamicPitchRatio) - pitchRatio = v->pitchRatio * tsf_timecents2Secsd(v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch); + pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor; if (dynamicGain) - noteGain = v->noteGain * tsf_decibelsToGain(v->modlfo.level * tmpModLfoToVolume); + noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume)); gainMono = noteGain * v->ampenv.level; @@ -1453,22 +1446,39 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc); TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume)); TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch)); - TSF_BOOL isLooping = (v->loopSizeF32P32 > 0); - fixed32p32 tmpSampleEndF32P32 = (fixed32p32)(region->end) << 32; + TSF_BOOL isLooping = (v->loopStart < v->loopEnd); + unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd; + //double tmpSampleEndDbl = (double)v->sampleEnd, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0; + //double tmpSourceSamplePosition = v->sourceSamplePosition; + fixed32p32 tmpSampleEndF32P32 = ((fixed32p32)(region->end)) << 32; + fixed32p32 tmpLoopEndF32P32 = ((fixed32p32)(tmpLoopEnd + 1)) << 32; fixed32p32 tmpSourceSamplePositionF32P32 = v->sourceSamplePositionF32P32; + struct tsf_voice_lowpass tmpLowpass = v->lowpass; + + TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc); + float tmpSampleRate = f->outSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc; TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch); - fixed32p32 pitchRatioF32P32, tmpPitchRatioF32P32; + //double pitchRatio; + fixed32p32 pitchRatioF32P32; float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch; TSF_BOOL dynamicGain = (region->modLfoToVolume != 0); - float noteGain, tmpNoteGain, tmpModLfoToVolume; + float noteGain, tmpModLfoToVolume; - if (dynamicPitchRatio) tmpPitchRatioF32P32 = v->pitchRatioF32P32, pitchRatioF32P32 = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; - else pitchRatioF32P32 = v->pitchRatioF32P32, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; + if (dynamicLowpass) tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc; + else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0; - if (dynamicGain) noteGain = 0, tmpNoteGain = v->noteGain, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; - else noteGain = v->noteGain, tmpModLfoToVolume = 0; + if (dynamicPitchRatio) pitchRatioF32P32 = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; + else { + double pr = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor; + fixed32p32 adj = 1LL<<32; + pr *= adj; + pitchRatioF32P32 = (int64_t)pr, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; + } + + if (dynamicGain) noteGain = 0, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; + else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0; while (numSamples) { @@ -1476,17 +1486,19 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples); numSamples -= blockSamples; - if (dynamicPitchRatio) { - if (v->modlfo.level || v->viblfo.level || v->modenv.level) - pitchRatioF32P32 = tmpPitchRatioF32P32 * tsf_timecents2Secsd(v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch); - else - pitchRatioF32P32 = tmpPitchRatioF32P32; // If all levels are 0, just bypass conversion function + if (dynamicLowpass) + { + float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc; + tmpLowpass.active = (fres <= 13500.0f); + if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, tsf_cents2Hertz(fres) / tmpSampleRate); } - if (dynamicGain) { - if (v->modlfo.level) noteGain = tmpNoteGain * tsf_decibelsToGain(v->modlfo.level * tmpModLfoToVolume); - else noteGain = tmpNoteGain; // If level is 0, just bypass conversion function - } + if (dynamicPitchRatio) { + pitchRatioF32P32 = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor * (1LL<<32); + } + + if (dynamicGain) + noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume)); gainMono = noteGain * v->ampenv.level; short gainMonoFP = gainMono * 32767; @@ -1499,7 +1511,7 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples); if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples); - while (blockSamples--) + while (blockSamples-- && tmpSourceSamplePositionF32P32 < tmpSampleEndF32P32) { unsigned int pos = (unsigned int)(tmpSourceSamplePositionF32P32>>32); if (pos == 0xffffffff) pos = 0; @@ -1511,14 +1523,8 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff // Next sample. tmpSourceSamplePositionF32P32 += pitchRatioF32P32; - - if (tmpSourceSamplePositionF32P32 >= v->loopEndF32P32) - { - if (isLooping) - tmpSourceSamplePositionF32P32 -= v->loopSizeF32P32; - else if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32) - break; - } + if (tmpSourceSamplePositionF32P32 >= tmpLoopEndF32P32 && isLooping) + tmpSourceSamplePositionF32P32 -= (tmpLoopEndF32P32 - tmpLoopStart + (1LL<<32)); } if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32 || v->ampenv.segment == TSF_SEGMENT_DONE) @@ -1529,6 +1535,7 @@ static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuff } v->sourceSamplePositionF32P32 = tmpSourceSamplePositionF32P32; + if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass; } @@ -1723,14 +1730,13 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel) } voice = &f->voices[f->voiceNum - 4]; voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1; - voice[1].playIndex = voice[2].playIndex = voice[3].playIndex = -1; } voice->region = region; voice->playingPreset = preset_index; voice->playingKey = key; voice->playIndex = voicePlayIndex; - voice->noteGain = vel * tsf_decibelsToGain(f->globalGainDB - region->attenuation); + voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel); if (f->channels) { @@ -1746,6 +1752,7 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel) // Offset/end. voice->sourceSamplePosition = region->offset; + voice->sourceSamplePositionF32P32 = ((int64_t)region->offset)<< 32; // Loop. doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end); @@ -1770,86 +1777,6 @@ TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel) } } -/** - * Returns the generated playing index that can be used to identify all voices related to this note. - */ -TSFDEF int tsf_note_on_fast(tsf* f, int preset_index, int key, float vel) -{ - if (preset_index < 0 || preset_index >= f->presetNum) return -1; - if (!vel) { tsf_note_off(f, preset_index, key); return -1; } - if (f->presets[preset_index].regions == NULL) tsf_load_preset(f, f->hydra, preset_index); - - short midiVelocity = (short)(vel * 127); - struct tsf_region *region, *regionEnd; - - // Play all matching regions. - int voicePlayIndex = f->voicePlayIndex++; - for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++) - { - if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) continue; - - struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; - voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum; - if (region->group) - { - for (; v != vEnd; v++) - if (v->playingPreset == preset_index && v->region->group == region->group) tsf_voice_endquick(v, f->outSampleRate); - else if (v->playingPreset == -1 && !voice) voice = v; - } - else for (; v != vEnd; v++) if (v->playingPreset == -1) { voice = v; break; } - - if (!voice) - { - f->voiceNum += 4; - struct tsf_voice *saveVoice = f->voices; - f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice)); - if (!f->voices) { - f->voices = saveVoice; - printf("OOM, no room for new voice. Ignoring note_on\n"); - return -1; - } - voice = &f->voices[f->voiceNum - 4]; - voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1; - voice[1].playIndex = voice[2].playIndex = voice[3].playIndex = -1; - } - - voice->region = region; - voice->playingPreset = preset_index; - voice->playingKey = key; - voice->playIndex = voicePlayIndex; - voice->noteGain = vel * tsf_decibelsToGain(f->globalGainDB - region->attenuation); - - if (f->channels) - { - f->channels->setupVoice(f, voice); - } - else - { - tsf_voice_calcpitchratio(voice, 0, f->outSampleRate); - voice->pitchRatioF32P32 = voice->pitchRatio * (1LL << 32); - } - - // Offset/end. - voice->sourceSamplePositionF32P32 = ((int64_t)region->offset)<< 32; - - // Loop. - doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end); - voice->loopStartF32P32 = doLoop ? ((int64_t)region->loop_start + 1) << 32 : 0; - voice->loopEndF32P32 = doLoop ? ((int64_t)region->loop_end + 1) << 32 : 0; - voice->loopSizeF32P32 = doLoop ? voice->loopEndF32P32 - voice->loopStartF32P32 + (1LL << 32) : 0; - - // Setup envelopes. - tsf_voice_envelope_setup(&voice->ampenv, ®ion->ampenv, key, midiVelocity, TSF_TRUE, f->outSampleRate); - tsf_voice_envelope_setup(&voice->modenv, ®ion->modenv, key, midiVelocity, TSF_FALSE, f->outSampleRate); - - // Setup LFO filters. - tsf_voice_lfo_setup(&voice->modlfo, region->delayModLFO, region->freqModLFO, f->outSampleRate); - tsf_voice_lfo_setup(&voice->viblfo, region->delayVibLFO, region->freqVibLFO, f->outSampleRate); - } - - return voicePlayIndex; -} - TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel) { int preset_index = tsf_get_presetindex(f, bank, preset_number); @@ -1878,19 +1805,6 @@ TSFDEF void tsf_note_off(tsf* f, int preset_index, int key) } } -/** - * Stops all voices with the given playing index. If no key provided or if -1, fallbacks to tsf_note_off - */ -TSFDEF void tsf_note_off_fast(tsf* f, int preset_index, int key, int playIndex = -1) -{ - if (playIndex < 0) - tsf_note_off(f, preset_index, key); - else - for (struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; v != vEnd; v++) - if (v->playIndex == playIndex && v->playingPreset == preset_index && v->playingKey == key && v->ampenv.segment < TSF_SEGMENT_RELEASE) - tsf_voice_end(v, f->outSampleRate); -} - TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key) { int preset_index = tsf_get_presetindex(f, bank, preset_number); @@ -1970,7 +1884,7 @@ static void tsf_channel_setup_voice(tsf* f, struct tsf_voice* v) struct tsf_channel* c = &f->channels->channels[f->channels->activeChannel]; float newpan = v->region->pan + c->panOffset; v->playingChannel = f->channels->activeChannel; - v->noteGain *= tsf_decibelsToGain(c->gainDB); + v->noteGainDB += c->gainDB; tsf_voice_calcpitchratio(v, (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)), f->outSampleRate); if (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; } else if (newpan >= 0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; } @@ -2080,7 +1994,7 @@ TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume) if (gainDBChange == 0) return; for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++) if (v->playingChannel == channel && v->playingPreset != -1) - v->noteGain *= tsf_decibelsToGain(gainDBChange); + v->noteGainDB += gainDBChange; c->gainDB = gainDB; } @@ -2151,6 +2065,10 @@ TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel) tsf_voice_endquick(v, f->outSampleRate); } +TSFDEF void tsf_channel_set_volume_to_one(tsf* f, int channel){ + tsf_channel_set_volume(f, channel, 1.0f); +} + TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value) { struct tsf_channel* c = tsf_channel_init(f, channel); @@ -2176,7 +2094,7 @@ TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int co c->midiVolume = c->midiExpression = 16383; c->midiPan = 8192; c->bank = 0; - tsf_channel_set_volume(f, channel, 1.0f); + tsf_channel_set_volume_to_one(f, channel); tsf_channel_set_pan(f, channel, 0.5f); tsf_channel_set_pitchrange(f, channel, 2.0f); return; From 7c3f83215afbb4389473acffe55b99c15bfe757c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 17 Oct 2024 21:58:48 +0200 Subject: [PATCH 009/205] switch off midi for esp32 -> esp32 Compiler bug --- lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h index 8a1ac3f9a..79377c47e 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h +++ b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h @@ -21,6 +21,10 @@ #ifndef _AUDIOGENERATORMIDI_H #define _AUDIOGENERATORMIDI_H +#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__) +// Do not build, Espressif's GCC8+ has a compiler bug +#else // __GNUC__ == 8 + #include "AudioGenerator.h" #define TSF_NO_STDIO @@ -90,7 +94,7 @@ class AudioGeneratorMIDI : public AudioGenerator unsigned long earliest_time = 0; struct tonegen_status { /* current status of a tone generator */ - bool playing; /* is it playing? */ + bool playing; /* is it playing? */ char track; /* if so, which track is the note from? */ char note; /* what note is playing? */ char instrument; /* what instrument? */ @@ -176,6 +180,7 @@ class AudioGeneratorMIDI : public AudioGenerator short samplesRendered[256]; }; +#endif //__GNUC__ == 8 #endif From 58e3297b076ed5658b7c944b66b417cae41a2e43 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 17 Oct 2024 22:04:00 +0200 Subject: [PATCH 010/205] No midi since esp32 compiler bug --- lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp index 5f1c5f3a3..59b2d4807 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp +++ b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp @@ -58,6 +58,10 @@ #include "AudioGeneratorMIDI.h" +#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__) +// Do not build, Espressif's GCC8+ has a compiler bug +#else // __GNUC__ == 8 + #pragma GCC optimize ("O3") #define TSF_NO_STDIO @@ -637,3 +641,4 @@ void AudioGeneratorMIDI::MakeStreamFromAFS(AudioFileSource *src, tsf_stream *afs afs->size = &afs_size; } +#endif //__GNUC__ == 8 From ad65448e097a1692869d3d4aa8327c7124cc8538 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 17 Oct 2024 22:12:58 +0200 Subject: [PATCH 011/205] try to fix if condition --- lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp index 59b2d4807..0c41afa61 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp +++ b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.cpp @@ -58,7 +58,7 @@ #include "AudioGeneratorMIDI.h" -#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__) +#if defined(ESP32) // Do not build, Espressif's GCC8+ has a compiler bug #else // __GNUC__ == 8 From 73f755dda29bcc2ac182c6823e9c45c24def4774 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Thu, 17 Oct 2024 22:14:16 +0200 Subject: [PATCH 012/205] HASPmota support for page delet and object updates (#22311) --- CHANGELOG.md | 1 + .../lv_haspmota/src/embedded/lv_haspmota.be | 176 +- .../src/solidify/solidified_lv_haspmota.h | 2539 +++++++++-------- 3 files changed, 1461 insertions(+), 1255 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebdf907ce..49ca989e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. ### Changed - ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 (#22299) +- HASPmota support for page delet and object updates ### Fixed diff --git a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be index a1fc4b5e1..1332a3ec8 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be +++ b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be @@ -880,7 +880,7 @@ class lvh_obj : lvh_root def get_text_color(style_modifier) return self._lv_obj.get_style_text_color(style_modifier) end - def set_value_color(t) self.set_text_color(t) end + def set_value_color(t, style_modifier) self.set_text_color(t, style_modifier) end def get_value_color() return self.get_value_color() end #==================================================================== @@ -2413,6 +2413,39 @@ class lvh_page end end + #==================================================================== + # `delete` special attribute used to delete the object + #==================================================================== + # def set_delete(v) + # raise "type_error", "you cannot assign to 'delete'" + # end + # def get_delete() + # self._delete() + # return def () end + # end + def delete() + # iterate on all objects and try to delete + # we first get a copy of all ids so we can delete and continue iterating + # without fearing about an infinite loop + var page_ids = [] + for id: self._obj_id.keys() + page_ids.push(id) + end + # we iterate until the array is empty + var idx = 0 + while idx < size(page_ids) + var page_id = page_ids[idx] + if (page_id != 0) && self._obj_id.contains(page_id) + # first check if the id is still in the page - it could have been already removed if it's a sub-object + self._obj_id[page_id].delete() + end + idx += 1 + end + self._obj_id = {} # clear map + # remove from page + self._hm._remove_page(self._page_id) + end + #==================================================================== # `show` transition from one page to another # duration: in ms, default 500 ms @@ -2818,6 +2851,23 @@ class HASPmota end end + #==================================================================== + # Remove page by id + # + # Should not be called directly. Indirectly called by `p.delete` + # + # Only removes reference to the page at root level + # Change the active page if needed + #==================================================================== + def _remove_page(page_id) + # check if we remove the active page + # TODO XXX + # remove object from page object + if self.lvh_pages.contains(page_id) + self.lvh_pages.remove(page_id) + end + end + #==================================================================== # Event CB handling #==================================================================== @@ -2856,65 +2906,70 @@ class HASPmota #==================================================================== # Parse single object + # + # The object may be pre-existing or brand new #==================================================================== def parse_obj(jline, page) import global import introspect var obj_id = int(jline.find("id")) # id number or nil - var obj_type = str(jline.find("obj")) # obj class or nil - var obj_lvh # lvgl object created - var lvh_page_cur = self.get_page_cur() # current page object + var obj_type = jline.find("obj") # obj class or nil + obj_type = (obj_type != nil) ? str(obj_type) : nil + var lvh_page_cur = self.get_page_cur() # current page object, cannot be nil - # first run any Berry code embedded - var berry_run = str(jline.find("berry_run")) - var func_compiled - if berry_run != "nil" - try - func_compiled = compile(berry_run) - except .. as e,m - print(format("HSP: unable to compile berry code \"%s\" - '%s' - %s", berry_run, e, m)) + # Step 1. Check the id for valid range + # 'obj_id' must be between 1 and 254 + if (obj_id != nil) && (obj_id < 0 || obj_id > 254) + if (obj_id != 0) || (obj_type == nil) + # if `obj_id` is not `nil` and not `0`, it must have `obj_type` not set to `nil` + print(f"HSP: invalid 'id': {obj_id} for 'obj': {obj_type}") + return end end - # if line contains botn 'obj' and 'id', create the object - if obj_type != "nil" && obj_id != nil - # 'obj_id' must be between 1 and 254 - if obj_id < 1 || obj_id > 254 - print("HSP: invalid 'id': " + str(obj_id) + " for 'obj':" + obj_type) - return - end + # Step 2. Check if the p<>b<> object already exists + # `prev_obj` contains the pre-existing object, or `nil` if we create a new object + var obj_lvh = lvh_page_cur.get_obj(obj_id) # get reference of object or `nil` if new object + + # Step 3. Create object instance if required + if (obj_type != nil) && (obj_id != nil) && (obj_lvh == nil) + + # Step 3.a. extract the LVGL parent object to create the object in the appropriate lvgl screen + # Result in `parent_lvgl` # extract haspmota class, prefix with `lvh_`. Ex: `btn` becomes `lvh_btn` - # extract parent - var parent_lvgl - var parent_id = int(jline.find("parentid")) + var parent_id = int(jline.find("parentid")) # id of parent object, or `nil` + var parent_obj # parent HASPmota object + var parent_lvgl # lvgl object of parent object - var parent_obj if parent_id != nil parent_obj = lvh_page_cur.get_obj(parent_id) # get parent object - if parent_obj != nil parent_lvgl = parent_obj._lv_obj end # parent + if parent_obj != nil + parent_lvgl = parent_obj._lv_obj + end # parent end if parent_lvgl == nil parent_lvgl = lvh_page_cur.get_scr() # if not parent, use the current page screen end + # Step 3.b. Get the HASPmota class object for the `obj` class # check if a class with the requested name exists # first look for a class with name `lvh_` exists var obj_class = introspect.get(self, "lvh_" + obj_type) - var lv_instance = nil # allows to pre-instanciate the object + var lv_instance # allows to pre-instanciate the object - # there is no lvh_X class, try to load the class name from the global namespace + # Step 3.c. if no native `lvh_` is found, try the class name from the global namespace if obj_class == nil # if not found, check if a LVGL class with name `lv_` exists var lv_cl = introspect.get(global, obj_type) - if lv_cl != nil && type(lv_cl) == 'class' + if (lv_cl != nil) && (type(lv_cl) == 'class') lv_instance = lv_cl(parent_lvgl) obj_class = self.lvh_obj # use the basic lvh_obj component to encapsulate end end - # still not found, try to load a module with the name of the class + # Step 3.d. if not found, try to load a module with the name of the class if obj_class == nil var lv_cl = introspect.module(obj_type) if lv_cl != nil && type(lv_cl) == 'class' @@ -2923,18 +2978,55 @@ class HASPmota end end + # Step 3.e. if none found, raise an error and abort if obj_class == nil - print("HSP: Cannot find object of type " + str(obj_type)) + print(f"HSP: Cannot find object of type {obj_type}") return end - - # instanciate the object, passing the lvgl screen as parent object + + # Step 3.f. instanciate the object, passing the lvgl screen as parent object obj_lvh = obj_class(parent_lvgl, page, jline, lv_instance, parent_obj) - # add object to page object + # Step 3.g. Add object to page object lvh_page_cur.add_obj(obj_id, obj_lvh) end + # Step 4. if "id" is 0, get the screen object + if obj_id == 0 + if (obj_type != nil) + print(f"HSP: cannot specify 'obj':'{obj_type}' for 'id':0") + return + end + obj_lvh = self.get_page_cur().get_obj(0) # get object id '0' + end + + # Step 5. apply attributes + # set attributes + # try every attribute, if not supported it is silently ignored + if (obj_lvh != nil) + for k:jline.keys() + obj_lvh.(k) = jline[k] + end + end + + # Step 6. apply post-config + # finally call 'post_config()' when all attributes are set, which gives an opportunity to clean or refresh + if (obj_lvh != nil) + obj_lvh.post_config() + end + + # Step 7. run any Berry code embedded + # `func_compiled` contains compiled code, that will be run once the object is complete, or `nil` if no code + # `berry_run` contains the actual source code, used only for logging + var func_compiled + var berry_run = str(jline.find("berry_run")) + if berry_run != "nil" + try + func_compiled = compile(berry_run) + except .. as e,m + print(format("HSP: unable to compile berry code \"%s\" - '%s' - %s", berry_run, e, m)) + end + end if func_compiled != nil try # run the compiled code once @@ -2947,26 +3039,6 @@ class HASPmota end end - if obj_id == nil return end # if no object id, ignore line - if obj_id == 0 && obj_type != "nil" - print("HSP: cannot specify 'obj' for 'id':0") - return - end - - # if id==0, retrieve the 'scr' object of the current page - if obj_id == 0 - obj_lvh = self.get_page_cur().get_obj(0) # get object id '0' - end - - # set attributes - # try every attribute, if not supported it is silently ignored - for k:jline.keys() - # introspect.set(obj, k, jline[k]) - obj_lvh.(k) = jline[k] - end - - # finally call 'post_config()' when all attributes are set, which gives an opportunity to clean or refresh - obj_lvh.post_config() end end haspmota.HASPmota = HASPmota diff --git a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h index 059ac6950..b8aee1c67 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h +++ b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h @@ -2228,8 +2228,8 @@ be_local_closure(class_lvh_obj_get_radius2, /* name */ ********************************************************************/ be_local_closure(class_lvh_obj_set_value_color, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 7, /* nstack */ + 3, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -2239,11 +2239,12 @@ be_local_closure(class_lvh_obj_set_value_color, /* name */ &be_ktab_class_lvh_obj, /* shared constants */ be_str_weak(set_value_color), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C080126, // 0000 GETMET R2 R0 K38 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0x8C0C0126, // 0000 GETMET R3 R0 K38 + 0x5C140200, // 0001 MOVE R5 R1 + 0x5C180400, // 0002 MOVE R6 R2 + 0x7C0C0600, // 0003 CALL R3 3 + 0x80000000, // 0004 RET 0 }) ) ); @@ -10205,152 +10206,51 @@ be_local_class(lvh_scr, })), be_str_weak(lvh_scr) ); -// compact class 'lvh_page' ktab size: 32, total: 51 (saved 152 bytes) -static const bvalue be_ktab_class_lvh_page[32] = { - /* K0 */ be_nested_str_weak(global), - /* K1 */ be_nested_str_weak(_hm), - /* K2 */ be_const_int(1), - /* K3 */ be_nested_str_weak(_page_id), - /* K4 */ be_nested_str_weak(_obj_id), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(_lv_scr), - /* K7 */ be_nested_str_weak(lv), - /* K8 */ be_nested_str_weak(layer_top), - /* K9 */ be_nested_str_weak(obj), - /* K10 */ be_nested_str_weak(scr_act), - /* K11 */ be_nested_str_weak(get_style_bg_color), - /* K12 */ be_nested_str_weak(set_style_bg_color), - /* K13 */ be_nested_str_weak(lvh_scr), - /* K14 */ be_nested_str_weak(p), - /* K15 */ be_nested_str_weak(b0), - /* K16 */ be_nested_str_weak(find), - /* K17 */ be_nested_str_weak(p_X25ib_X25i), - /* K18 */ be_nested_str_weak(_page), - /* K19 */ be_nested_str_weak(id), - /* K20 */ be_nested_str_weak(_p), - /* K21 */ be_nested_str_weak(page_dir_to), - /* K22 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25i_X22_X3A_X22out_X22_X7D_X7D), - /* K23 */ be_nested_str_weak(lvh_page_cur_idx), - /* K24 */ be_nested_str_weak(tasmota), - /* K25 */ be_nested_str_weak(set_timer), - /* K26 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25i_X22_X3A_X22in_X22_X7D_X7D), - /* K27 */ be_nested_str_weak(screen_load), - /* K28 */ be_nested_str_weak(show_anim), - /* K29 */ be_nested_str_weak(SCR_LOAD_ANIM_NONE), - /* K30 */ be_nested_str_weak(screen_load_anim), - /* K31 */ be_nested_str_weak(remove), +// compact class 'lvh_page' ktab size: 38, total: 62 (saved 192 bytes) +static const bvalue be_ktab_class_lvh_page[38] = { + /* K0 */ be_nested_str_weak(_page_id), + /* K1 */ be_nested_str_weak(_obj_id), + /* K2 */ be_nested_str_weak(find), + /* K3 */ be_nested_str_weak(remove), + /* K4 */ be_nested_str_weak(p_X25ib_X25i), + /* K5 */ be_nested_str_weak(_page), + /* K6 */ be_nested_str_weak(id), + /* K7 */ be_nested_str_weak(global), + /* K8 */ be_nested_str_weak(_hm), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(0), + /* K11 */ be_nested_str_weak(_lv_scr), + /* K12 */ be_nested_str_weak(lv), + /* K13 */ be_nested_str_weak(layer_top), + /* K14 */ be_nested_str_weak(obj), + /* K15 */ be_nested_str_weak(scr_act), + /* K16 */ be_nested_str_weak(get_style_bg_color), + /* K17 */ be_nested_str_weak(set_style_bg_color), + /* K18 */ be_nested_str_weak(lvh_scr), + /* K19 */ be_nested_str_weak(p), + /* K20 */ be_nested_str_weak(b0), + /* K21 */ be_nested_str_weak(keys), + /* K22 */ be_nested_str_weak(push), + /* K23 */ be_nested_str_weak(stop_iteration), + /* K24 */ be_nested_str_weak(contains), + /* K25 */ be_nested_str_weak(delete), + /* K26 */ be_nested_str_weak(_remove_page), + /* K27 */ be_nested_str_weak(_p), + /* K28 */ be_nested_str_weak(page_dir_to), + /* K29 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25i_X22_X3A_X22out_X22_X7D_X7D), + /* K30 */ be_nested_str_weak(lvh_page_cur_idx), + /* K31 */ be_nested_str_weak(tasmota), + /* K32 */ be_nested_str_weak(set_timer), + /* K33 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25i_X22_X3A_X22in_X22_X7D_X7D), + /* K34 */ be_nested_str_weak(screen_load), + /* K35 */ be_nested_str_weak(show_anim), + /* K36 */ be_nested_str_weak(SCR_LOAD_ANIM_NONE), + /* K37 */ be_nested_str_weak(screen_load_anim), }; extern const bclass be_class_lvh_page; -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(class_lvh_page_init, /* name */ - be_nested_proto( - 10, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[59]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0x90020202, // 0001 SETMBR R0 K1 R2 - 0x60100009, // 0002 GETGBL R4 G9 - 0x5C140200, // 0003 MOVE R5 R1 - 0x7C100200, // 0004 CALL R4 1 - 0x5C040800, // 0005 MOVE R1 R4 - 0x4C100000, // 0006 LDNIL R4 - 0x1C100204, // 0007 EQ R4 R1 R4 - 0x78120000, // 0008 JMPF R4 #000A - 0x58040002, // 0009 LDCONST R1 K2 - 0x90020601, // 000A SETMBR R0 K3 R1 - 0x60100013, // 000B GETGBL R4 G19 - 0x7C100000, // 000C CALL R4 0 - 0x90020804, // 000D SETMBR R0 K4 R4 - 0x1C100305, // 000E EQ R4 R1 K5 - 0x78120004, // 000F JMPF R4 #0015 - 0xB8120E00, // 0010 GETNGBL R4 K7 - 0x8C100908, // 0011 GETMET R4 R4 K8 - 0x7C100200, // 0012 CALL R4 1 - 0x90020C04, // 0013 SETMBR R0 K6 R4 - 0x7002000F, // 0014 JMP #0025 - 0xB8120E00, // 0015 GETNGBL R4 K7 - 0x8C100909, // 0016 GETMET R4 R4 K9 - 0x58180005, // 0017 LDCONST R6 K5 - 0x7C100400, // 0018 CALL R4 2 - 0x90020C04, // 0019 SETMBR R0 K6 R4 - 0xB8120E00, // 001A GETNGBL R4 K7 - 0x8C10090A, // 001B GETMET R4 R4 K10 - 0x7C100200, // 001C CALL R4 1 - 0x8C10090B, // 001D GETMET R4 R4 K11 - 0x58180005, // 001E LDCONST R6 K5 - 0x7C100400, // 001F CALL R4 2 - 0x88140106, // 0020 GETMBR R5 R0 K6 - 0x8C140B0C, // 0021 GETMET R5 R5 K12 - 0x5C1C0800, // 0022 MOVE R7 R4 - 0x58200005, // 0023 LDCONST R8 K5 - 0x7C140600, // 0024 CALL R5 3 - 0x88100101, // 0025 GETMBR R4 R0 K1 - 0x8810090D, // 0026 GETMBR R4 R4 K13 - 0x5C140800, // 0027 MOVE R5 R4 - 0x4C180000, // 0028 LDNIL R6 - 0x5C1C0000, // 0029 MOVE R7 R0 - 0x4C200000, // 002A LDNIL R8 - 0x88240106, // 002B GETMBR R9 R0 K6 - 0x7C140800, // 002C CALL R5 4 - 0x88180104, // 002D GETMBR R6 R0 K4 - 0x981A0A05, // 002E SETIDX R6 K5 R5 - 0x60180008, // 002F GETGBL R6 G8 - 0x881C0103, // 0030 GETMBR R7 R0 K3 - 0x7C180200, // 0031 CALL R6 1 - 0x001A1C06, // 0032 ADD R6 K14 R6 - 0x900C0C00, // 0033 SETMBR R3 R6 R0 - 0x60180008, // 0034 GETGBL R6 G8 - 0x881C0103, // 0035 GETMBR R7 R0 K3 - 0x7C180200, // 0036 CALL R6 1 - 0x001A1C06, // 0037 ADD R6 K14 R6 - 0x00180D0F, // 0038 ADD R6 R6 K15 - 0x900C0C05, // 0039 SETMBR R3 R6 R5 - 0x80000000, // 003A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_scr -********************************************************************/ -be_local_closure(class_lvh_page_get_scr, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(get_scr), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040106, // 0000 GETMBR R1 R0 K6 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: id ********************************************************************/ @@ -10368,7 +10268,7 @@ be_local_closure(class_lvh_page_id, /* name */ be_str_weak(id), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ - 0x88040103, // 0000 GETMBR R1 R0 K3 + 0x88040100, // 0000 GETMBR R1 R0 K0 0x80040200, // 0001 RET 1 R1 }) ) @@ -10377,11 +10277,11 @@ be_local_closure(class_lvh_page_id, /* name */ /******************************************************************** -** Solidified function: get_obj +** Solidified function: remove_obj ********************************************************************/ -be_local_closure(class_lvh_page_get_obj, /* name */ +be_local_closure(class_lvh_page_remove_obj, /* name */ be_nested_proto( - 5, /* nstack */ + 7, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -10390,14 +10290,111 @@ be_local_closure(class_lvh_page_get_obj, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(get_obj), + be_str_weak(remove_obj), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 - 0x8C080510, // 0001 GETMET R2 R2 K16 + ( &(const binstruction[20]) { /* code */ + 0x88080101, // 0000 GETMBR R2 R0 K1 + 0x8C080502, // 0001 GETMET R2 R2 K2 0x5C100200, // 0002 MOVE R4 R1 0x7C080400, // 0003 CALL R2 2 - 0x80040400, // 0004 RET 1 R2 + 0x880C0101, // 0004 GETMBR R3 R0 K1 + 0x8C0C0703, // 0005 GETMET R3 R3 K3 + 0x5C140200, // 0006 MOVE R5 R1 + 0x7C0C0400, // 0007 CALL R3 2 + 0x780A0009, // 0008 JMPF R2 #0013 + 0x600C0018, // 0009 GETGBL R3 G24 + 0x58100004, // 000A LDCONST R4 K4 + 0x88140505, // 000B GETMBR R5 R2 K5 + 0x8C140B06, // 000C GETMET R5 R5 K6 + 0x7C140200, // 000D CALL R5 1 + 0x5C180200, // 000E MOVE R6 R1 + 0x7C0C0600, // 000F CALL R3 3 + 0xB8120E00, // 0010 GETNGBL R4 K7 + 0x4C140000, // 0011 LDNIL R5 + 0x90100605, // 0012 SETMBR R4 R3 R5 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(class_lvh_page_init, /* name */ + be_nested_proto( + 10, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_lvh_page, /* shared constants */ + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[59]) { /* code */ + 0xA40E0E00, // 0000 IMPORT R3 K7 + 0x90021002, // 0001 SETMBR R0 K8 R2 + 0x60100009, // 0002 GETGBL R4 G9 + 0x5C140200, // 0003 MOVE R5 R1 + 0x7C100200, // 0004 CALL R4 1 + 0x5C040800, // 0005 MOVE R1 R4 + 0x4C100000, // 0006 LDNIL R4 + 0x1C100204, // 0007 EQ R4 R1 R4 + 0x78120000, // 0008 JMPF R4 #000A + 0x58040009, // 0009 LDCONST R1 K9 + 0x90020001, // 000A SETMBR R0 K0 R1 + 0x60100013, // 000B GETGBL R4 G19 + 0x7C100000, // 000C CALL R4 0 + 0x90020204, // 000D SETMBR R0 K1 R4 + 0x1C10030A, // 000E EQ R4 R1 K10 + 0x78120004, // 000F JMPF R4 #0015 + 0xB8121800, // 0010 GETNGBL R4 K12 + 0x8C10090D, // 0011 GETMET R4 R4 K13 + 0x7C100200, // 0012 CALL R4 1 + 0x90021604, // 0013 SETMBR R0 K11 R4 + 0x7002000F, // 0014 JMP #0025 + 0xB8121800, // 0015 GETNGBL R4 K12 + 0x8C10090E, // 0016 GETMET R4 R4 K14 + 0x5818000A, // 0017 LDCONST R6 K10 + 0x7C100400, // 0018 CALL R4 2 + 0x90021604, // 0019 SETMBR R0 K11 R4 + 0xB8121800, // 001A GETNGBL R4 K12 + 0x8C10090F, // 001B GETMET R4 R4 K15 + 0x7C100200, // 001C CALL R4 1 + 0x8C100910, // 001D GETMET R4 R4 K16 + 0x5818000A, // 001E LDCONST R6 K10 + 0x7C100400, // 001F CALL R4 2 + 0x8814010B, // 0020 GETMBR R5 R0 K11 + 0x8C140B11, // 0021 GETMET R5 R5 K17 + 0x5C1C0800, // 0022 MOVE R7 R4 + 0x5820000A, // 0023 LDCONST R8 K10 + 0x7C140600, // 0024 CALL R5 3 + 0x88100108, // 0025 GETMBR R4 R0 K8 + 0x88100912, // 0026 GETMBR R4 R4 K18 + 0x5C140800, // 0027 MOVE R5 R4 + 0x4C180000, // 0028 LDNIL R6 + 0x5C1C0000, // 0029 MOVE R7 R0 + 0x4C200000, // 002A LDNIL R8 + 0x8824010B, // 002B GETMBR R9 R0 K11 + 0x7C140800, // 002C CALL R5 4 + 0x88180101, // 002D GETMBR R6 R0 K1 + 0x981A1405, // 002E SETIDX R6 K10 R5 + 0x60180008, // 002F GETGBL R6 G8 + 0x881C0100, // 0030 GETMBR R7 R0 K0 + 0x7C180200, // 0031 CALL R6 1 + 0x001A2606, // 0032 ADD R6 K19 R6 + 0x900C0C00, // 0033 SETMBR R3 R6 R0 + 0x60180008, // 0034 GETGBL R6 G8 + 0x881C0100, // 0035 GETMBR R7 R0 K0 + 0x7C180200, // 0036 CALL R6 1 + 0x001A2606, // 0037 ADD R6 K19 R6 + 0x00180D14, // 0038 ADD R6 R6 K20 + 0x900C0C05, // 0039 SETMBR R3 R6 R5 + 0x80000000, // 003A RET 0 }) ) ); @@ -10421,16 +10418,16 @@ be_local_closure(class_lvh_page_add_obj, /* name */ be_str_weak(add_obj), &be_const_str_solidified, ( &(const binstruction[12]) { /* code */ - 0x880C0104, // 0000 GETMBR R3 R0 K4 + 0x880C0101, // 0000 GETMBR R3 R0 K1 0x980C0202, // 0001 SETIDX R3 R1 R2 0x600C0018, // 0002 GETGBL R3 G24 - 0x58100011, // 0003 LDCONST R4 K17 - 0x88140512, // 0004 GETMBR R5 R2 K18 - 0x8C140B13, // 0005 GETMET R5 R5 K19 + 0x58100004, // 0003 LDCONST R4 K4 + 0x88140505, // 0004 GETMBR R5 R2 K5 + 0x8C140B06, // 0005 GETMET R5 R5 K6 0x7C140200, // 0006 CALL R5 1 0x5C180200, // 0007 MOVE R6 R1 0x7C0C0600, // 0008 CALL R3 3 - 0xB8120000, // 0009 GETNGBL R4 K0 + 0xB8120E00, // 0009 GETNGBL R4 K7 0x90100602, // 000A SETMBR R4 R3 R2 0x80000000, // 000B RET 0 }) @@ -10439,6 +10436,74 @@ be_local_closure(class_lvh_page_add_obj, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: delete +********************************************************************/ +be_local_closure(class_lvh_page_delete, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_lvh_page, /* shared constants */ + be_str_weak(delete), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0x60040012, // 0000 GETGBL R1 G18 + 0x7C040000, // 0001 CALL R1 0 + 0x60080010, // 0002 GETGBL R2 G16 + 0x880C0101, // 0003 GETMBR R3 R0 K1 + 0x8C0C0715, // 0004 GETMET R3 R3 K21 + 0x7C0C0200, // 0005 CALL R3 1 + 0x7C080200, // 0006 CALL R2 1 + 0xA8020005, // 0007 EXBLK 0 #000E + 0x5C0C0400, // 0008 MOVE R3 R2 + 0x7C0C0000, // 0009 CALL R3 0 + 0x8C100316, // 000A GETMET R4 R1 K22 + 0x5C180600, // 000B MOVE R6 R3 + 0x7C100400, // 000C CALL R4 2 + 0x7001FFF9, // 000D JMP #0008 + 0x58080017, // 000E LDCONST R2 K23 + 0xAC080200, // 000F CATCH R2 1 0 + 0xB0080000, // 0010 RAISE 2 R0 R0 + 0x5808000A, // 0011 LDCONST R2 K10 + 0x600C000C, // 0012 GETGBL R3 G12 + 0x5C100200, // 0013 MOVE R4 R1 + 0x7C0C0200, // 0014 CALL R3 1 + 0x140C0403, // 0015 LT R3 R2 R3 + 0x780E000D, // 0016 JMPF R3 #0025 + 0x940C0202, // 0017 GETIDX R3 R1 R2 + 0x2010070A, // 0018 NE R4 R3 K10 + 0x78120008, // 0019 JMPF R4 #0023 + 0x88100101, // 001A GETMBR R4 R0 K1 + 0x8C100918, // 001B GETMET R4 R4 K24 + 0x5C180600, // 001C MOVE R6 R3 + 0x7C100400, // 001D CALL R4 2 + 0x78120003, // 001E JMPF R4 #0023 + 0x88100101, // 001F GETMBR R4 R0 K1 + 0x94100803, // 0020 GETIDX R4 R4 R3 + 0x8C100919, // 0021 GETMET R4 R4 K25 + 0x7C100200, // 0022 CALL R4 1 + 0x00080509, // 0023 ADD R2 R2 K9 + 0x7001FFEC, // 0024 JMP #0012 + 0x600C0013, // 0025 GETGBL R3 G19 + 0x7C0C0000, // 0026 CALL R3 0 + 0x90020203, // 0027 SETMBR R0 K1 R3 + 0x880C0108, // 0028 GETMBR R3 R0 K8 + 0x8C0C071A, // 0029 GETMET R3 R3 K26 + 0x88140100, // 002A GETMBR R5 R0 K0 + 0x7C0C0400, // 002B CALL R3 2 + 0x80000000, // 002C RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: show ********************************************************************/ @@ -10507,18 +10572,18 @@ be_local_closure(class_lvh_page_show, /* name */ be_str_weak(show), &be_const_str_solidified, ( &(const binstruction[73]) { /* code */ - 0x880C0106, // 0000 GETMBR R3 R0 K6 + 0x880C010B, // 0000 GETMBR R3 R0 K11 0x4C100000, // 0001 LDNIL R4 0x1C0C0604, // 0002 EQ R3 R3 R4 0x780E0001, // 0003 JMPF R3 #0006 0x4C0C0000, // 0004 LDNIL R3 0x80040600, // 0005 RET 1 R3 - 0x880C0106, // 0006 GETMBR R3 R0 K6 - 0x880C0714, // 0007 GETMBR R3 R3 K20 - 0xB8120E00, // 0008 GETNGBL R4 K7 - 0x8C10090A, // 0009 GETMET R4 R4 K10 + 0x880C010B, // 0006 GETMBR R3 R0 K11 + 0x880C071B, // 0007 GETMBR R3 R3 K27 + 0xB8121800, // 0008 GETNGBL R4 K12 + 0x8C10090F, // 0009 GETMET R4 R4 K15 0x7C100200, // 000A CALL R4 1 - 0x88100914, // 000B GETMBR R4 R4 K20 + 0x8810091B, // 000B GETMBR R4 R4 K27 0x1C0C0604, // 000C EQ R3 R3 R4 0x780E0000, // 000D JMPF R3 #000F 0x80000600, // 000E RET 0 @@ -10529,53 +10594,53 @@ be_local_closure(class_lvh_page_show, /* name */ 0x4C0C0000, // 0013 LDNIL R3 0x1C0C0203, // 0014 EQ R3 R1 R3 0x780E0005, // 0015 JMPF R3 #001C - 0x880C0101, // 0016 GETMBR R3 R0 K1 - 0x8C0C0715, // 0017 GETMET R3 R3 K21 - 0x8C140113, // 0018 GETMET R5 R0 K19 + 0x880C0108, // 0016 GETMBR R3 R0 K8 + 0x8C0C071C, // 0017 GETMET R3 R3 K28 + 0x8C140106, // 0018 GETMET R5 R0 K6 0x7C140200, // 0019 CALL R5 1 0x7C0C0400, // 001A CALL R3 2 0x5C040600, // 001B MOVE R1 R3 0x600C0018, // 001C GETGBL R3 G24 - 0x58100016, // 001D LDCONST R4 K22 - 0x88140101, // 001E GETMBR R5 R0 K1 - 0x88140B17, // 001F GETMBR R5 R5 K23 + 0x5810001D, // 001D LDCONST R4 K29 + 0x88140108, // 001E GETMBR R5 R0 K8 + 0x88140B1E, // 001F GETMBR R5 R5 K30 0x7C0C0400, // 0020 CALL R3 2 - 0xB8123000, // 0021 GETNGBL R4 K24 - 0x8C100919, // 0022 GETMET R4 R4 K25 - 0x58180005, // 0023 LDCONST R6 K5 + 0xB8123E00, // 0021 GETNGBL R4 K31 + 0x8C100920, // 0022 GETMET R4 R4 K32 + 0x5818000A, // 0023 LDCONST R6 K10 0x841C0000, // 0024 CLOSURE R7 P0 0x7C100600, // 0025 CALL R4 3 0x60100018, // 0026 GETGBL R4 G24 - 0x5814001A, // 0027 LDCONST R5 K26 - 0x88180103, // 0028 GETMBR R6 R0 K3 + 0x58140021, // 0027 LDCONST R5 K33 + 0x88180100, // 0028 GETMBR R6 R0 K0 0x7C100400, // 0029 CALL R4 2 - 0xB8163000, // 002A GETNGBL R5 K24 - 0x8C140B19, // 002B GETMET R5 R5 K25 - 0x581C0005, // 002C LDCONST R7 K5 + 0xB8163E00, // 002A GETNGBL R5 K31 + 0x8C140B20, // 002B GETMET R5 R5 K32 + 0x581C000A, // 002C LDCONST R7 K10 0x84200001, // 002D CLOSURE R8 P1 0x7C140600, // 002E CALL R5 3 - 0x88140101, // 002F GETMBR R5 R0 K1 - 0x88180103, // 0030 GETMBR R6 R0 K3 - 0x90162E06, // 0031 SETMBR R5 K23 R6 - 0x1C140305, // 0032 EQ R5 R1 K5 + 0x88140108, // 002F GETMBR R5 R0 K8 + 0x88180100, // 0030 GETMBR R6 R0 K0 + 0x90163C06, // 0031 SETMBR R5 K30 R6 + 0x1C14030A, // 0032 EQ R5 R1 K10 0x78160004, // 0033 JMPF R5 #0039 - 0xB8160E00, // 0034 GETNGBL R5 K7 - 0x8C140B1B, // 0035 GETMET R5 R5 K27 - 0x881C0106, // 0036 GETMBR R7 R0 K6 + 0xB8161800, // 0034 GETNGBL R5 K12 + 0x8C140B22, // 0035 GETMET R5 R5 K34 + 0x881C010B, // 0036 GETMBR R7 R0 K11 0x7C140400, // 0037 CALL R5 2 0x7002000D, // 0038 JMP #0047 - 0x8814011C, // 0039 GETMBR R5 R0 K28 - 0x8C140B10, // 003A GETMET R5 R5 K16 + 0x88140123, // 0039 GETMBR R5 R0 K35 + 0x8C140B02, // 003A GETMET R5 R5 K2 0x5C1C0200, // 003B MOVE R7 R1 - 0xB8220E00, // 003C GETNGBL R8 K7 - 0x8820111D, // 003D GETMBR R8 R8 K29 + 0xB8221800, // 003C GETNGBL R8 K12 + 0x88201124, // 003D GETMBR R8 R8 K36 0x7C140600, // 003E CALL R5 3 - 0xB81A0E00, // 003F GETNGBL R6 K7 - 0x8C180D1E, // 0040 GETMET R6 R6 K30 - 0x88200106, // 0041 GETMBR R8 R0 K6 + 0xB81A1800, // 003F GETNGBL R6 K12 + 0x8C180D25, // 0040 GETMET R6 R6 K37 + 0x8820010B, // 0041 GETMBR R8 R0 K11 0x5C240A00, // 0042 MOVE R9 R5 0x5C280400, // 0043 MOVE R10 R2 - 0x582C0005, // 0044 LDCONST R11 K5 + 0x582C000A, // 0044 LDCONST R11 K10 0x50300000, // 0045 LDBOOL R12 0 0 0x7C180C00, // 0046 CALL R6 6 0xA0000000, // 0047 CLOSE R0 @@ -10587,11 +10652,11 @@ be_local_closure(class_lvh_page_show, /* name */ /******************************************************************** -** Solidified function: remove_obj +** Solidified function: get_obj ********************************************************************/ -be_local_closure(class_lvh_page_remove_obj, /* name */ +be_local_closure(class_lvh_page_get_obj, /* name */ be_nested_proto( - 7, /* nstack */ + 5, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -10600,29 +10665,39 @@ be_local_closure(class_lvh_page_remove_obj, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(remove_obj), + be_str_weak(get_obj), &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 - 0x8C080510, // 0001 GETMET R2 R2 K16 + ( &(const binstruction[ 5]) { /* code */ + 0x88080101, // 0000 GETMBR R2 R0 K1 + 0x8C080502, // 0001 GETMET R2 R2 K2 0x5C100200, // 0002 MOVE R4 R1 0x7C080400, // 0003 CALL R2 2 - 0x880C0104, // 0004 GETMBR R3 R0 K4 - 0x8C0C071F, // 0005 GETMET R3 R3 K31 - 0x5C140200, // 0006 MOVE R5 R1 - 0x7C0C0400, // 0007 CALL R3 2 - 0x780A0009, // 0008 JMPF R2 #0013 - 0x600C0018, // 0009 GETGBL R3 G24 - 0x58100011, // 000A LDCONST R4 K17 - 0x88140512, // 000B GETMBR R5 R2 K18 - 0x8C140B13, // 000C GETMET R5 R5 K19 - 0x7C140200, // 000D CALL R5 1 - 0x5C180200, // 000E MOVE R6 R1 - 0x7C0C0600, // 000F CALL R3 3 - 0xB8120000, // 0010 GETNGBL R4 K0 - 0x4C140000, // 0011 LDNIL R5 - 0x90100605, // 0012 SETMBR R4 R3 R5 - 0x80000000, // 0013 RET 0 + 0x80040400, // 0004 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_scr +********************************************************************/ +be_local_closure(class_lvh_page_get_scr, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_lvh_page, /* shared constants */ + be_str_weak(get_scr), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x8804010B, // 0000 GETMBR R1 R0 K11 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -10635,13 +10710,12 @@ be_local_closure(class_lvh_page_remove_obj, /* name */ be_local_class(lvh_page, 7, NULL, - be_nested_map(15, + be_nested_map(16, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(init, -1), be_const_closure(class_lvh_page_init_closure) }, - { be_const_key_weak(back, 3), be_const_var(6) }, - { be_const_key_weak(next, -1), be_const_var(5) }, - { be_const_key_weak(remove_obj, 7), be_const_closure(class_lvh_page_remove_obj_closure) }, - { be_const_key_weak(_hm, -1), be_const_var(3) }, + { be_const_key_weak(id, 5), be_const_closure(class_lvh_page_id_closure) }, + { be_const_key_weak(_obj_id, -1), be_const_var(0) }, + { be_const_key_weak(back, -1), be_const_var(6) }, + { be_const_key_weak(remove_obj, 14), be_const_closure(class_lvh_page_remove_obj_closure) }, { be_const_key_weak(show_anim, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { be_const_map( * be_nested_map(5, ( (struct bmapnode*) &(const bmapnode[]) { @@ -10651,147 +10725,230 @@ be_local_class(lvh_page, { be_const_key_int(-1, -1), be_const_int(6) }, { be_const_key_int(-2, -1), be_const_int(7) }, })) ) } )) }, - { be_const_key_weak(id, 5), be_const_closure(class_lvh_page_id_closure) }, - { be_const_key_weak(show, 11), be_const_closure(class_lvh_page_show_closure) }, - { be_const_key_weak(get_obj, -1), be_const_closure(class_lvh_page_get_obj_closure) }, + { be_const_key_weak(prev, -1), be_const_var(4) }, { be_const_key_weak(add_obj, -1), be_const_closure(class_lvh_page_add_obj_closure) }, - { be_const_key_weak(_obj_id, -1), be_const_var(0) }, - { be_const_key_weak(prev, 12), be_const_var(4) }, - { be_const_key_weak(_lv_scr, 13), be_const_var(2) }, - { be_const_key_weak(get_scr, 14), be_const_closure(class_lvh_page_get_scr_closure) }, - { be_const_key_weak(_page_id, -1), be_const_var(1) }, + { be_const_key_weak(get_scr, -1), be_const_closure(class_lvh_page_get_scr_closure) }, + { be_const_key_weak(next, -1), be_const_var(5) }, + { be_const_key_weak(get_obj, -1), be_const_closure(class_lvh_page_get_obj_closure) }, + { be_const_key_weak(delete, -1), be_const_closure(class_lvh_page_delete_closure) }, + { be_const_key_weak(_lv_scr, -1), be_const_var(2) }, + { be_const_key_weak(show, 7), be_const_closure(class_lvh_page_show_closure) }, + { be_const_key_weak(_hm, 9), be_const_var(3) }, + { be_const_key_weak(_page_id, 15), be_const_var(1) }, + { be_const_key_weak(init, -1), be_const_closure(class_lvh_page_init_closure) }, })), be_str_weak(lvh_page) ); extern const bclass be_class_HASPmota; -// compact class 'HASPmota' ktab size: 121, total: 179 (saved 464 bytes) -static const bvalue be_ktab_class_HASPmota[121] = { - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str_weak(lvh_page_cur_idx), - /* K2 */ be_nested_str_weak(lvh_pages), - /* K3 */ be_nested_str_weak(keys), - /* K4 */ be_nested_str_weak(push), - /* K5 */ be_nested_str_weak(stop_iteration), - /* K6 */ be_nested_str_weak(sort), - /* K7 */ be_nested_str_weak(find), - /* K8 */ be_const_int(1), - /* K9 */ be_nested_str_weak(pages_list_sorted), - /* K10 */ be_nested_str_weak(prev), - /* K11 */ be_nested_str_weak(next), - /* K12 */ be_nested_str_weak(back), - /* K13 */ be_nested_str_weak(re_page_target), - /* K14 */ be_nested_str_weak(match), - /* K15 */ be_nested_str_weak(show), - /* K16 */ be_nested_str_weak(cb), - /* K17 */ be_nested_str_weak(introspect), - /* K18 */ be_nested_str_weak(event_cb), - /* K19 */ be_nested_str_weak(gen_cb), - /* K20 */ be_nested_str_weak(_lv_obj), - /* K21 */ be_nested_str_weak(add_event_cb), - /* K22 */ be_nested_str_weak(toptr), - /* K23 */ be_nested_str_weak(json), - /* K24 */ be_nested_str_weak(load), - /* K25 */ be_nested_str_weak(instance), - /* K26 */ be_nested_str_weak(parse_page), - /* K27 */ be_nested_str_weak(parse_obj), - /* K28 */ be_nested_str_weak(value_error), - /* K29 */ be_nested_str_weak(unable_X20to_X20parse_X20JSON_X20line), - /* K30 */ be_nested_str_weak(event), - /* K31 */ be_nested_str_weak(_p), - /* K32 */ be_nested_str_weak(lv), - /* K33 */ be_nested_str_weak(lv_event), - /* K34 */ be_nested_str_weak(get_user_data), - /* K35 */ be_nested_str_weak(fromptr), - /* K36 */ be_nested_str_weak(fix_lv_version), - /* K37 */ be_nested_str_weak(re), - /* K38 */ be_nested_str_weak(compile), - /* K39 */ be_nested_str_weak(p_X5Cd_X2B), - /* K40 */ be_const_class(be_class_HASPmota), - /* K41 */ be_nested_str_weak(get), - /* K42 */ be_nested_str_weak(version), - /* K43 */ be_nested_str_weak(int), - /* K44 */ be_nested_str_weak(global), - /* K45 */ be_nested_str_weak(id), - /* K46 */ be_nested_str_weak(obj), - /* K47 */ be_nested_str_weak(get_page_cur), - /* K48 */ be_nested_str_weak(berry_run), - /* K49 */ be_nested_str_weak(nil), - /* K50 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K51 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20), - /* K52 */ be_nested_str_weak(_X20for_X20_X27obj_X27_X3A), - /* K53 */ be_nested_str_weak(parentid), - /* K54 */ be_nested_str_weak(get_obj), - /* K55 */ be_nested_str_weak(get_scr), - /* K56 */ be_nested_str_weak(lvh_), - /* K57 */ be_nested_str_weak(class), - /* K58 */ be_nested_str_weak(lvh_obj), - /* K59 */ be_nested_str_weak(module), - /* K60 */ be_nested_str_weak(HSP_X3A_X20Cannot_X20find_X20object_X20of_X20type_X20), - /* K61 */ be_nested_str_weak(add_obj), - /* K62 */ be_nested_str_weak(function), - /* K63 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K64 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X20for_X20_X27id_X27_X3A0), - /* K65 */ be_nested_str_weak(post_config), - /* K66 */ be_nested_str_weak(string), - /* K67 */ be_nested_str_weak(r), - /* K68 */ be_nested_str_weak(read), - /* K69 */ be_nested_str_weak(close), - /* K70 */ be_nested_str_weak(split), - /* K71 */ be_nested_str_weak(_X0A), - /* K72 */ be_nested_str_weak(tasmota), - /* K73 */ be_nested_str_weak(loglevel), - /* K74 */ be_nested_str_weak(log), - /* K75 */ be_nested_str_weak(HSP_X3A_X20parsing_X20line_X20_X27_X25s_X27), - /* K76 */ be_nested_str_weak(no_X20page_X20_X27id_X27_X20defined), - /* K77 */ be_nested_str_weak(tr), - /* K78 */ be_nested_str_weak(_X20_X09), - /* K79 */ be_nested_str_weak(), - /* K80 */ be_nested_str_weak(HSP_X3A_X20invalid_X20JSON_X20line_X20_X27_X25s_X27), - /* K81 */ be_const_int(2), - /* K82 */ be_nested_str_weak(remove), - /* K83 */ be_nested_str_weak(no_X20page_X20object_X20defined), - /* K84 */ be_nested_str_weak(EVENT_CLICKED), - /* K85 */ be_nested_str_weak(page_show), - /* K86 */ be_nested_str_weak(_action), - /* K87 */ be_nested_str_weak(has), - /* K88 */ be_nested_str_weak(page), - /* K89 */ be_nested_str_weak(contains), - /* K90 */ be_nested_str_weak(lvh_page), - /* K91 */ be_nested_str_weak(path), - /* K92 */ be_nested_str_weak(def_templ_name), - /* K93 */ be_nested_str_weak(exists), - /* K94 */ be_nested_str_weak(file_X20_X27), - /* K95 */ be_nested_str_weak(_X27_X20not_X20found), - /* K96 */ be_nested_str_weak(io_erorr), - /* K97 */ be_nested_str_weak(start), - /* K98 */ be_nested_str_weak(dark), - /* K99 */ be_nested_str_weak(hres), - /* K100 */ be_nested_str_weak(get_hor_res), - /* K101 */ be_nested_str_weak(vres), - /* K102 */ be_nested_str_weak(get_ver_res), - /* K103 */ be_nested_str_weak(scr), - /* K104 */ be_nested_str_weak(scr_act), - /* K105 */ be_nested_str_weak(r16), - /* K106 */ be_nested_str_weak(font_embedded), - /* K107 */ be_nested_str_weak(robotocondensed), - /* K108 */ be_nested_str_weak(montserrat), - /* K109 */ be_nested_str_weak(theme_haspmota_init), - /* K110 */ be_nested_str_weak(color), - /* K111 */ be_const_int(16711935), - /* K112 */ be_const_int(3158064), - /* K113 */ be_nested_str_weak(get_disp), - /* K114 */ be_nested_str_weak(set_theme), - /* K115 */ be_nested_str_weak(set_style_bg_color), - /* K116 */ be_const_int(16777215), - /* K117 */ be_nested_str_weak(theme_apply), - /* K118 */ be_nested_str_weak(layer_top), - /* K119 */ be_nested_str_weak(set_style_bg_opa), - /* K120 */ be_nested_str_weak(_load), +// compact class 'HASPmota' ktab size: 120, total: 180 (saved 480 bytes) +static const bvalue be_ktab_class_HASPmota[120] = { + /* K0 */ be_const_class(be_class_HASPmota), + /* K1 */ be_nested_str_weak(introspect), + /* K2 */ be_nested_str_weak(get), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(version), + /* K5 */ be_nested_str_weak(int), + /* K6 */ be_nested_str_weak(json), + /* K7 */ be_nested_str_weak(load), + /* K8 */ be_nested_str_weak(instance), + /* K9 */ be_nested_str_weak(parse_page), + /* K10 */ be_nested_str_weak(parse_obj), + /* K11 */ be_nested_str_weak(lvh_pages), + /* K12 */ be_nested_str_weak(lvh_page_cur_idx), + /* K13 */ be_nested_str_weak(value_error), + /* K14 */ be_nested_str_weak(unable_X20to_X20parse_X20JSON_X20line), + /* K15 */ be_const_int(0), + /* K16 */ be_nested_str_weak(keys), + /* K17 */ be_nested_str_weak(push), + /* K18 */ be_nested_str_weak(stop_iteration), + /* K19 */ be_nested_str_weak(sort), + /* K20 */ be_nested_str_weak(find), + /* K21 */ be_const_int(1), + /* K22 */ be_nested_str_weak(fix_lv_version), + /* K23 */ be_nested_str_weak(re), + /* K24 */ be_nested_str_weak(re_page_target), + /* K25 */ be_nested_str_weak(compile), + /* K26 */ be_nested_str_weak(p_X5Cd_X2B), + /* K27 */ be_nested_str_weak(has), + /* K28 */ be_nested_str_weak(page), + /* K29 */ be_nested_str_weak(contains), + /* K30 */ be_nested_str_weak(lvh_page), + /* K31 */ be_nested_str_weak(id), + /* K32 */ be_nested_str_weak(get_page_cur), + /* K33 */ be_nested_str_weak(prev), + /* K34 */ be_nested_str_weak(next), + /* K35 */ be_nested_str_weak(back), + /* K36 */ be_nested_str_weak(EVENT_CLICKED), + /* K37 */ be_nested_str_weak(page_show), + /* K38 */ be_nested_str_weak(_action), + /* K39 */ be_nested_str_weak(cb), + /* K40 */ be_nested_str_weak(event_cb), + /* K41 */ be_nested_str_weak(gen_cb), + /* K42 */ be_nested_str_weak(_lv_obj), + /* K43 */ be_nested_str_weak(add_event_cb), + /* K44 */ be_nested_str_weak(toptr), + /* K45 */ be_nested_str_weak(string), + /* K46 */ be_nested_str_weak(r), + /* K47 */ be_nested_str_weak(read), + /* K48 */ be_nested_str_weak(close), + /* K49 */ be_nested_str_weak(split), + /* K50 */ be_nested_str_weak(_X0A), + /* K51 */ be_nested_str_weak(tasmota), + /* K52 */ be_nested_str_weak(loglevel), + /* K53 */ be_nested_str_weak(log), + /* K54 */ be_nested_str_weak(HSP_X3A_X20parsing_X20line_X20_X27_X25s_X27), + /* K55 */ be_nested_str_weak(no_X20page_X20_X27id_X27_X20defined), + /* K56 */ be_nested_str_weak(tr), + /* K57 */ be_nested_str_weak(_X20_X09), + /* K58 */ be_nested_str_weak(), + /* K59 */ be_nested_str_weak(HSP_X3A_X20invalid_X20JSON_X20line_X20_X27_X25s_X27), + /* K60 */ be_const_int(2), + /* K61 */ be_nested_str_weak(remove), + /* K62 */ be_nested_str_weak(pages_list_sorted), + /* K63 */ be_nested_str_weak(no_X20page_X20object_X20defined), + /* K64 */ be_nested_str_weak(show), + /* K65 */ be_nested_str_weak(match), + /* K66 */ be_nested_str_weak(path), + /* K67 */ be_nested_str_weak(def_templ_name), + /* K68 */ be_nested_str_weak(exists), + /* K69 */ be_nested_str_weak(file_X20_X27), + /* K70 */ be_nested_str_weak(_X27_X20not_X20found), + /* K71 */ be_nested_str_weak(io_erorr), + /* K72 */ be_nested_str_weak(start), + /* K73 */ be_nested_str_weak(dark), + /* K74 */ be_nested_str_weak(hres), + /* K75 */ be_nested_str_weak(get_hor_res), + /* K76 */ be_nested_str_weak(vres), + /* K77 */ be_nested_str_weak(get_ver_res), + /* K78 */ be_nested_str_weak(scr), + /* K79 */ be_nested_str_weak(scr_act), + /* K80 */ be_nested_str_weak(r16), + /* K81 */ be_nested_str_weak(font_embedded), + /* K82 */ be_nested_str_weak(robotocondensed), + /* K83 */ be_nested_str_weak(montserrat), + /* K84 */ be_nested_str_weak(theme_haspmota_init), + /* K85 */ be_nested_str_weak(color), + /* K86 */ be_const_int(16711935), + /* K87 */ be_const_int(3158064), + /* K88 */ be_nested_str_weak(get_disp), + /* K89 */ be_nested_str_weak(set_theme), + /* K90 */ be_nested_str_weak(set_style_bg_color), + /* K91 */ be_const_int(16777215), + /* K92 */ be_nested_str_weak(theme_apply), + /* K93 */ be_nested_str_weak(layer_top), + /* K94 */ be_nested_str_weak(set_style_bg_opa), + /* K95 */ be_nested_str_weak(_load), + /* K96 */ be_nested_str_weak(global), + /* K97 */ be_nested_str_weak(obj), + /* K98 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20_X25s_X20for_X20_X27obj_X27_X3A_X20_X25s), + /* K99 */ be_nested_str_weak(get_obj), + /* K100 */ be_nested_str_weak(parentid), + /* K101 */ be_nested_str_weak(get_scr), + /* K102 */ be_nested_str_weak(lvh_), + /* K103 */ be_nested_str_weak(class), + /* K104 */ be_nested_str_weak(lvh_obj), + /* K105 */ be_nested_str_weak(module), + /* K106 */ be_nested_str_weak(HSP_X3A_X20Cannot_X20find_X20object_X20of_X20type_X20_X25s), + /* K107 */ be_nested_str_weak(add_obj), + /* K108 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X3A_X27_X25s_X27_X20for_X20_X27id_X27_X3A0), + /* K109 */ be_nested_str_weak(post_config), + /* K110 */ be_nested_str_weak(berry_run), + /* K111 */ be_nested_str_weak(nil), + /* K112 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K113 */ be_nested_str_weak(function), + /* K114 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K115 */ be_nested_str_weak(event), + /* K116 */ be_nested_str_weak(_p), + /* K117 */ be_nested_str_weak(lv_event), + /* K118 */ be_nested_str_weak(get_user_data), + /* K119 */ be_nested_str_weak(fromptr), }; extern const bclass be_class_HASPmota; +/******************************************************************** +** Solidified function: fix_lv_version +********************************************************************/ +be_local_closure(class_HASPmota_fix_lv_version, /* name */ + be_nested_proto( + 6, /* nstack */ + 0, /* argc */ + 12, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(fix_lv_version), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x58000000, // 0000 LDCONST R0 K0 + 0xA4060200, // 0001 IMPORT R1 K1 + 0x8C080302, // 0002 GETMET R2 R1 K2 + 0xB8120600, // 0003 GETNGBL R4 K3 + 0x58140004, // 0004 LDCONST R5 K4 + 0x7C080600, // 0005 CALL R2 3 + 0x600C0004, // 0006 GETGBL R3 G4 + 0x5C100400, // 0007 MOVE R4 R2 + 0x7C0C0200, // 0008 CALL R3 1 + 0x200C0705, // 0009 NE R3 R3 K5 + 0x780E0002, // 000A JMPF R3 #000E + 0xB80E0600, // 000B GETNGBL R3 K3 + 0x54120007, // 000C LDINT R4 8 + 0x900E0804, // 000D SETMBR R3 K4 R4 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse +********************************************************************/ +be_local_closure(class_HASPmota_parse, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(parse), + &be_const_str_solidified, + ( &(const binstruction[21]) { /* code */ + 0xA40A0C00, // 0000 IMPORT R2 K6 + 0x8C0C0507, // 0001 GETMET R3 R2 K7 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x60100004, // 0004 GETGBL R4 G4 + 0x5C140600, // 0005 MOVE R5 R3 + 0x7C100200, // 0006 CALL R4 1 + 0x1C100908, // 0007 EQ R4 R4 K8 + 0x78120009, // 0008 JMPF R4 #0013 + 0x8C100109, // 0009 GETMET R4 R0 K9 + 0x5C180600, // 000A MOVE R6 R3 + 0x7C100400, // 000B CALL R4 2 + 0x8C10010A, // 000C GETMET R4 R0 K10 + 0x5C180600, // 000D MOVE R6 R3 + 0x881C010B, // 000E GETMBR R7 R0 K11 + 0x8820010C, // 000F GETMBR R8 R0 K12 + 0x941C0E08, // 0010 GETIDX R7 R7 R8 + 0x7C100600, // 0011 CALL R4 3 + 0x70020000, // 0012 JMP #0014 + 0xB0061B0E, // 0013 RAISE 1 K13 K14 + 0x80000000, // 0014 RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: pages_list_sorted ********************************************************************/ @@ -10811,27 +10968,27 @@ be_local_closure(class_HASPmota_pages_list_sorted, /* name */ ( &(const binstruction[47]) { /* code */ 0x60080012, // 0000 GETGBL R2 G18 0x7C080000, // 0001 CALL R2 0 - 0x1C0C0300, // 0002 EQ R3 R1 K0 + 0x1C0C030F, // 0002 EQ R3 R1 K15 0x780E0000, // 0003 JMPF R3 #0005 - 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x8804010C, // 0004 GETMBR R1 R0 K12 0x600C0010, // 0005 GETGBL R3 G16 - 0x88100102, // 0006 GETMBR R4 R0 K2 - 0x8C100903, // 0007 GETMET R4 R4 K3 + 0x8810010B, // 0006 GETMBR R4 R0 K11 + 0x8C100910, // 0007 GETMET R4 R4 K16 0x7C100200, // 0008 CALL R4 1 0x7C0C0200, // 0009 CALL R3 1 0xA8020007, // 000A EXBLK 0 #0013 0x5C100600, // 000B MOVE R4 R3 0x7C100000, // 000C CALL R4 0 - 0x20140900, // 000D NE R5 R4 K0 + 0x2014090F, // 000D NE R5 R4 K15 0x78160002, // 000E JMPF R5 #0012 - 0x8C140504, // 000F GETMET R5 R2 K4 + 0x8C140511, // 000F GETMET R5 R2 K17 0x5C1C0800, // 0010 MOVE R7 R4 0x7C140400, // 0011 CALL R5 2 0x7001FFF7, // 0012 JMP #000B - 0x580C0005, // 0013 LDCONST R3 K5 + 0x580C0012, // 0013 LDCONST R3 K18 0xAC0C0200, // 0014 CATCH R3 1 0 0xB0080000, // 0015 RAISE 2 R0 R0 - 0x8C0C0106, // 0016 GETMET R3 R0 K6 + 0x8C0C0113, // 0016 GETMET R3 R0 K19 0x5C140400, // 0017 MOVE R5 R2 0x7C0C0400, // 0018 CALL R3 2 0x5C080600, // 0019 MOVE R2 R3 @@ -10843,7 +11000,7 @@ be_local_closure(class_HASPmota_pages_list_sorted, /* name */ 0x5C100400, // 001F MOVE R4 R2 0x7C0C0200, // 0020 CALL R3 1 0x00080402, // 0021 ADD R2 R2 R2 - 0x8C100507, // 0022 GETMET R4 R2 K7 + 0x8C100514, // 0022 GETMET R4 R2 K20 0x5C180200, // 0023 MOVE R6 R1 0x7C100400, // 0024 CALL R4 2 0x4C140000, // 0025 LDNIL R5 @@ -10852,7 +11009,7 @@ be_local_closure(class_HASPmota_pages_list_sorted, /* name */ 0x4C140000, // 0028 LDNIL R5 0x80040A00, // 0029 RET 1 R5 0x00140803, // 002A ADD R5 R4 R3 - 0x04140B08, // 002B SUB R5 R5 K8 + 0x04140B15, // 002B SUB R5 R5 K21 0x40140805, // 002C CONNECT R5 R4 R5 0x94080405, // 002D GETIDX R2 R2 R5 0x80040400, // 002E RET 1 R2 @@ -10863,11 +11020,69 @@ be_local_closure(class_HASPmota_pages_list_sorted, /* name */ /******************************************************************** -** Solidified function: page_show +** Solidified function: init ********************************************************************/ -be_local_closure(class_HASPmota_page_show, /* name */ +be_local_closure(class_HASPmota_init, /* name */ be_nested_proto( - 8, /* nstack */ + 5, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x8C040116, // 0000 GETMET R1 R0 K22 + 0x7C040200, // 0001 CALL R1 1 + 0xA4062E00, // 0002 IMPORT R1 K23 + 0x8C080319, // 0003 GETMET R2 R1 K25 + 0x5810001A, // 0004 LDCONST R4 K26 + 0x7C080400, // 0005 CALL R2 2 + 0x90023002, // 0006 SETMBR R0 K24 R2 + 0x80000000, // 0007 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_page_cur +********************************************************************/ +be_local_closure(class_HASPmota_get_page_cur, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(get_page_cur), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8804010B, // 0000 GETMBR R1 R0 K11 + 0x8808010C, // 0001 GETMBR R2 R0 K12 + 0x94040202, // 0002 GETIDX R1 R1 R2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_page +********************************************************************/ +be_local_closure(class_HASPmota_parse_page, /* name */ + be_nested_proto( + 9, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -10876,80 +11091,95 @@ be_local_closure(class_HASPmota_page_show, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(page_show), + be_str_weak(parse_page), &be_const_str_solidified, - ( &(const binstruction[71]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x880C0102, // 0001 GETMBR R3 R0 K2 - 0x88100101, // 0002 GETMBR R4 R0 K1 - 0x940C0604, // 0003 GETIDX R3 R3 R4 - 0x8C100109, // 0004 GETMET R4 R0 K9 - 0x88180101, // 0005 GETMBR R6 R0 K1 - 0x7C100400, // 0006 CALL R4 2 - 0x6014000C, // 0007 GETGBL R5 G12 - 0x5C180800, // 0008 MOVE R6 R4 - 0x7C140200, // 0009 CALL R5 1 - 0x18140B08, // 000A LE R5 R5 K8 - 0x78160000, // 000B JMPF R5 #000D - 0x80000A00, // 000C RET 0 - 0x1C14030A, // 000D EQ R5 R1 K10 - 0x78160009, // 000E JMPF R5 #0019 - 0x60140009, // 000F GETGBL R5 G9 - 0x8818070A, // 0010 GETMBR R6 R3 K10 - 0x7C140200, // 0011 CALL R5 1 - 0x5C080A00, // 0012 MOVE R2 R5 - 0x4C140000, // 0013 LDNIL R5 - 0x1C140405, // 0014 EQ R5 R2 R5 - 0x78160001, // 0015 JMPF R5 #0018 - 0x5415FFFE, // 0016 LDINT R5 -1 - 0x94080805, // 0017 GETIDX R2 R4 R5 - 0x70020023, // 0018 JMP #003D - 0x1C14030B, // 0019 EQ R5 R1 K11 - 0x78160008, // 001A JMPF R5 #0024 - 0x60140009, // 001B GETGBL R5 G9 - 0x8818070B, // 001C GETMBR R6 R3 K11 - 0x7C140200, // 001D CALL R5 1 - 0x5C080A00, // 001E MOVE R2 R5 - 0x4C140000, // 001F LDNIL R5 - 0x1C140405, // 0020 EQ R5 R2 R5 - 0x78160000, // 0021 JMPF R5 #0023 - 0x94080908, // 0022 GETIDX R2 R4 K8 - 0x70020018, // 0023 JMP #003D - 0x1C14030C, // 0024 EQ R5 R1 K12 - 0x7816000B, // 0025 JMPF R5 #0032 - 0x60140009, // 0026 GETGBL R5 G9 - 0x8818070C, // 0027 GETMBR R6 R3 K12 - 0x7C140200, // 0028 CALL R5 1 - 0x5C080A00, // 0029 MOVE R2 R5 - 0x4C140000, // 002A LDNIL R5 - 0x1C140405, // 002B EQ R5 R2 R5 - 0x78160003, // 002C JMPF R5 #0031 - 0x8C140109, // 002D GETMET R5 R0 K9 - 0x4C1C0000, // 002E LDNIL R7 - 0x7C140400, // 002F CALL R5 2 - 0x94080B00, // 0030 GETIDX R2 R5 K0 - 0x7002000A, // 0031 JMP #003D - 0x8814010D, // 0032 GETMBR R5 R0 K13 - 0x8C140B0E, // 0033 GETMET R5 R5 K14 - 0x5C1C0200, // 0034 MOVE R7 R1 - 0x7C140400, // 0035 CALL R5 2 - 0x78160005, // 0036 JMPF R5 #003D - 0x60140009, // 0037 GETGBL R5 G9 - 0x5419FFFE, // 0038 LDINT R6 -1 - 0x401A1006, // 0039 CONNECT R6 K8 R6 - 0x94180206, // 003A GETIDX R6 R1 R6 - 0x7C140200, // 003B CALL R5 1 - 0x5C080A00, // 003C MOVE R2 R5 - 0x4C140000, // 003D LDNIL R5 - 0x20140405, // 003E NE R5 R2 R5 - 0x78160005, // 003F JMPF R5 #0046 - 0x24140500, // 0040 GT R5 R2 K0 - 0x78160003, // 0041 JMPF R5 #0046 - 0x88140102, // 0042 GETMBR R5 R0 K2 - 0x94140A02, // 0043 GETIDX R5 R5 R2 - 0x8C140B0F, // 0044 GETMET R5 R5 K15 - 0x7C140200, // 0045 CALL R5 1 - 0x80000000, // 0046 RET 0 + ( &(const binstruction[54]) { /* code */ + 0x8C08031B, // 0000 GETMET R2 R1 K27 + 0x5810001C, // 0001 LDCONST R4 K28 + 0x7C080400, // 0002 CALL R2 2 + 0x780A0030, // 0003 JMPF R2 #0035 + 0x60080004, // 0004 GETGBL R2 G4 + 0x940C031C, // 0005 GETIDX R3 R1 K28 + 0x7C080200, // 0006 CALL R2 1 + 0x1C080505, // 0007 EQ R2 R2 K5 + 0x780A002B, // 0008 JMPF R2 #0035 + 0x60080009, // 0009 GETGBL R2 G9 + 0x940C031C, // 000A GETIDX R3 R1 K28 + 0x7C080200, // 000B CALL R2 1 + 0x90021802, // 000C SETMBR R0 K12 R2 + 0x880C010B, // 000D GETMBR R3 R0 K11 + 0x8C0C071D, // 000E GETMET R3 R3 K29 + 0x5C140400, // 000F MOVE R5 R2 + 0x7C0C0400, // 0010 CALL R3 2 + 0x740E0006, // 0011 JMPT R3 #0019 + 0x880C011E, // 0012 GETMBR R3 R0 K30 + 0x8810010B, // 0013 GETMBR R4 R0 K11 + 0x5C140600, // 0014 MOVE R5 R3 + 0x5C180400, // 0015 MOVE R6 R2 + 0x5C1C0000, // 0016 MOVE R7 R0 + 0x7C140400, // 0017 CALL R5 2 + 0x98100405, // 0018 SETIDX R4 R2 R5 + 0x8C0C0314, // 0019 GETMET R3 R1 K20 + 0x5814001F, // 001A LDCONST R5 K31 + 0x7C0C0400, // 001B CALL R3 2 + 0x1C0C070F, // 001C EQ R3 R3 K15 + 0x780E0016, // 001D JMPF R3 #0035 + 0x8C0C0120, // 001E GETMET R3 R0 K32 + 0x7C0C0200, // 001F CALL R3 1 + 0x60100009, // 0020 GETGBL R4 G9 + 0x8C140314, // 0021 GETMET R5 R1 K20 + 0x581C0021, // 0022 LDCONST R7 K33 + 0x4C200000, // 0023 LDNIL R8 + 0x7C140600, // 0024 CALL R5 3 + 0x7C100200, // 0025 CALL R4 1 + 0x900E4204, // 0026 SETMBR R3 K33 R4 + 0x60100009, // 0027 GETGBL R4 G9 + 0x8C140314, // 0028 GETMET R5 R1 K20 + 0x581C0022, // 0029 LDCONST R7 K34 + 0x4C200000, // 002A LDNIL R8 + 0x7C140600, // 002B CALL R5 3 + 0x7C100200, // 002C CALL R4 1 + 0x900E4404, // 002D SETMBR R3 K34 R4 + 0x60100009, // 002E GETGBL R4 G9 + 0x8C140314, // 002F GETMET R5 R1 K20 + 0x581C0023, // 0030 LDCONST R7 K35 + 0x4C200000, // 0031 LDNIL R8 + 0x7C140600, // 0032 CALL R5 3 + 0x7C100200, // 0033 CALL R4 1 + 0x900E4604, // 0034 SETMBR R3 K35 R4 + 0x80000000, // 0035 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: do_action +********************************************************************/ +be_local_closure(class_HASPmota_do_action, /* name */ + be_nested_proto( + 6, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(do_action), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0xB80E0600, // 0000 GETNGBL R3 K3 + 0x880C0724, // 0001 GETMBR R3 R3 K36 + 0x200C0403, // 0002 NE R3 R2 R3 + 0x780E0000, // 0003 JMPF R3 #0005 + 0x80000600, // 0004 RET 0 + 0x8C0C0125, // 0005 GETMET R3 R0 K37 + 0x88140326, // 0006 GETMBR R5 R1 K38 + 0x7C0C0400, // 0007 CALL R3 2 + 0x80000000, // 0008 RET 0 }) ) ); @@ -10998,21 +11228,21 @@ be_local_closure(class_HASPmota_register_event, /* name */ be_str_weak(register_event), &be_const_str_solidified, ( &(const binstruction[20]) { /* code */ - 0xA40E2000, // 0000 IMPORT R3 K16 - 0xA4122200, // 0001 IMPORT R4 K17 - 0x88140112, // 0002 GETMBR R5 R0 K18 + 0xA40E4E00, // 0000 IMPORT R3 K39 + 0xA4120200, // 0001 IMPORT R4 K1 + 0x88140128, // 0002 GETMBR R5 R0 K40 0x4C180000, // 0003 LDNIL R6 0x1C140A06, // 0004 EQ R5 R5 R6 0x78160003, // 0005 JMPF R5 #000A - 0x8C140713, // 0006 GETMET R5 R3 K19 + 0x8C140729, // 0006 GETMET R5 R3 K41 0x841C0000, // 0007 CLOSURE R7 P0 0x7C140400, // 0008 CALL R5 2 - 0x90022405, // 0009 SETMBR R0 K18 R5 - 0x88140314, // 000A GETMBR R5 R1 K20 - 0x8C180B15, // 000B GETMET R6 R5 K21 - 0x88200112, // 000C GETMBR R8 R0 K18 + 0x90025005, // 0009 SETMBR R0 K40 R5 + 0x8814032A, // 000A GETMBR R5 R1 K42 + 0x8C180B2B, // 000B GETMET R6 R5 K43 + 0x88200128, // 000C GETMBR R8 R0 K40 0x5C240400, // 000D MOVE R9 R2 - 0x8C280916, // 000E GETMET R10 R4 K22 + 0x8C28092C, // 000E GETMET R10 R4 K44 0x5C300200, // 000F MOVE R12 R1 0x7C280400, // 0010 CALL R10 2 0x7C180800, // 0011 CALL R6 4 @@ -11024,414 +11254,6 @@ be_local_closure(class_HASPmota_register_event, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: parse -********************************************************************/ -be_local_closure(class_HASPmota_parse, /* name */ - be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(parse), - &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0xA40A2E00, // 0000 IMPORT R2 K23 - 0x8C0C0518, // 0001 GETMET R3 R2 K24 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x60100004, // 0004 GETGBL R4 G4 - 0x5C140600, // 0005 MOVE R5 R3 - 0x7C100200, // 0006 CALL R4 1 - 0x1C100919, // 0007 EQ R4 R4 K25 - 0x78120009, // 0008 JMPF R4 #0013 - 0x8C10011A, // 0009 GETMET R4 R0 K26 - 0x5C180600, // 000A MOVE R6 R3 - 0x7C100400, // 000B CALL R4 2 - 0x8C10011B, // 000C GETMET R4 R0 K27 - 0x5C180600, // 000D MOVE R6 R3 - 0x881C0102, // 000E GETMBR R7 R0 K2 - 0x88200101, // 000F GETMBR R8 R0 K1 - 0x941C0E08, // 0010 GETIDX R7 R7 R8 - 0x7C100600, // 0011 CALL R4 3 - 0x70020000, // 0012 JMP #0014 - 0xB006391D, // 0013 RAISE 1 K28 K29 - 0x80000000, // 0014 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: event_dispatch -********************************************************************/ -be_local_closure(class_HASPmota_event_dispatch, /* name */ - be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(event_dispatch), - &be_const_str_solidified, - ( &(const binstruction[34]) { /* code */ - 0xA40A2200, // 0000 IMPORT R2 K17 - 0x8C0C0516, // 0001 GETMET R3 R2 K22 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x8810011E, // 0004 GETMBR R4 R0 K30 - 0x78120002, // 0005 JMPF R4 #0009 - 0x8810011E, // 0006 GETMBR R4 R0 K30 - 0x90123E03, // 0007 SETMBR R4 K31 R3 - 0x70020004, // 0008 JMP #000E - 0xB8124000, // 0009 GETNGBL R4 K32 - 0x8C100921, // 000A GETMET R4 R4 K33 - 0x5C180600, // 000B MOVE R6 R3 - 0x7C100400, // 000C CALL R4 2 - 0x90023C04, // 000D SETMBR R0 K30 R4 - 0x8810011E, // 000E GETMBR R4 R0 K30 - 0x8C100922, // 000F GETMET R4 R4 K34 - 0x7C100200, // 0010 CALL R4 1 - 0x60140009, // 0011 GETGBL R5 G9 - 0x5C180800, // 0012 MOVE R6 R4 - 0x7C140200, // 0013 CALL R5 1 - 0x20140B00, // 0014 NE R5 R5 K0 - 0x7816000A, // 0015 JMPF R5 #0021 - 0x8C140523, // 0016 GETMET R5 R2 K35 - 0x5C1C0800, // 0017 MOVE R7 R4 - 0x7C140400, // 0018 CALL R5 2 - 0x60180004, // 0019 GETGBL R6 G4 - 0x5C1C0A00, // 001A MOVE R7 R5 - 0x7C180200, // 001B CALL R6 1 - 0x1C180D19, // 001C EQ R6 R6 K25 - 0x781A0002, // 001D JMPF R6 #0021 - 0x8C180B12, // 001E GETMET R6 R5 K18 - 0x8820011E, // 001F GETMBR R8 R0 K30 - 0x7C180400, // 0020 CALL R6 2 - 0x80000000, // 0021 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(class_HASPmota_init, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x8C040124, // 0000 GETMET R1 R0 K36 - 0x7C040200, // 0001 CALL R1 1 - 0xA4064A00, // 0002 IMPORT R1 K37 - 0x8C080326, // 0003 GETMET R2 R1 K38 - 0x58100027, // 0004 LDCONST R4 K39 - 0x7C080400, // 0005 CALL R2 2 - 0x90021A02, // 0006 SETMBR R0 K13 R2 - 0x80000000, // 0007 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: fix_lv_version -********************************************************************/ -be_local_closure(class_HASPmota_fix_lv_version, /* name */ - be_nested_proto( - 6, /* nstack */ - 0, /* argc */ - 12, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(fix_lv_version), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x58000028, // 0000 LDCONST R0 K40 - 0xA4062200, // 0001 IMPORT R1 K17 - 0x8C080329, // 0002 GETMET R2 R1 K41 - 0xB8124000, // 0003 GETNGBL R4 K32 - 0x5814002A, // 0004 LDCONST R5 K42 - 0x7C080600, // 0005 CALL R2 3 - 0x600C0004, // 0006 GETGBL R3 G4 - 0x5C100400, // 0007 MOVE R4 R2 - 0x7C0C0200, // 0008 CALL R3 1 - 0x200C072B, // 0009 NE R3 R3 K43 - 0x780E0002, // 000A JMPF R3 #000E - 0xB80E4000, // 000B GETNGBL R3 K32 - 0x54120007, // 000C LDINT R4 8 - 0x900E5404, // 000D SETMBR R3 K42 R4 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: parse_obj -********************************************************************/ -be_local_closure(class_HASPmota_parse_obj, /* name */ - be_nested_proto( - 22, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(parse_obj), - &be_const_str_solidified, - ( &(const binstruction[215]) { /* code */ - 0xA40E5800, // 0000 IMPORT R3 K44 - 0xA4122200, // 0001 IMPORT R4 K17 - 0x60140009, // 0002 GETGBL R5 G9 - 0x8C180307, // 0003 GETMET R6 R1 K7 - 0x5820002D, // 0004 LDCONST R8 K45 - 0x7C180400, // 0005 CALL R6 2 - 0x7C140200, // 0006 CALL R5 1 - 0x60180008, // 0007 GETGBL R6 G8 - 0x8C1C0307, // 0008 GETMET R7 R1 K7 - 0x5824002E, // 0009 LDCONST R9 K46 - 0x7C1C0400, // 000A CALL R7 2 - 0x7C180200, // 000B CALL R6 1 - 0x4C1C0000, // 000C LDNIL R7 - 0x8C20012F, // 000D GETMET R8 R0 K47 - 0x7C200200, // 000E CALL R8 1 - 0x60240008, // 000F GETGBL R9 G8 - 0x8C280307, // 0010 GETMET R10 R1 K7 - 0x58300030, // 0011 LDCONST R12 K48 - 0x7C280400, // 0012 CALL R10 2 - 0x7C240200, // 0013 CALL R9 1 - 0x4C280000, // 0014 LDNIL R10 - 0x202C1331, // 0015 NE R11 R9 K49 - 0x782E0012, // 0016 JMPF R11 #002A - 0xA8020005, // 0017 EXBLK 0 #001E - 0x602C000D, // 0018 GETGBL R11 G13 - 0x5C301200, // 0019 MOVE R12 R9 - 0x7C2C0200, // 001A CALL R11 1 - 0x5C281600, // 001B MOVE R10 R11 - 0xA8040001, // 001C EXBLK 1 1 - 0x7002000B, // 001D JMP #002A - 0xAC2C0002, // 001E CATCH R11 0 2 - 0x70020008, // 001F JMP #0029 - 0x60340001, // 0020 GETGBL R13 G1 - 0x60380018, // 0021 GETGBL R14 G24 - 0x583C0032, // 0022 LDCONST R15 K50 - 0x5C401200, // 0023 MOVE R16 R9 - 0x5C441600, // 0024 MOVE R17 R11 - 0x5C481800, // 0025 MOVE R18 R12 - 0x7C380800, // 0026 CALL R14 4 - 0x7C340200, // 0027 CALL R13 1 - 0x70020000, // 0028 JMP #002A - 0xB0080000, // 0029 RAISE 2 R0 R0 - 0x202C0D31, // 002A NE R11 R6 K49 - 0x782E006A, // 002B JMPF R11 #0097 - 0x4C2C0000, // 002C LDNIL R11 - 0x202C0A0B, // 002D NE R11 R5 R11 - 0x782E0067, // 002E JMPF R11 #0097 - 0x142C0B08, // 002F LT R11 R5 K8 - 0x742E0002, // 0030 JMPT R11 #0034 - 0x542E00FD, // 0031 LDINT R11 254 - 0x242C0A0B, // 0032 GT R11 R5 R11 - 0x782E0008, // 0033 JMPF R11 #003D - 0x602C0001, // 0034 GETGBL R11 G1 - 0x60300008, // 0035 GETGBL R12 G8 - 0x5C340A00, // 0036 MOVE R13 R5 - 0x7C300200, // 0037 CALL R12 1 - 0x0032660C, // 0038 ADD R12 K51 R12 - 0x00301934, // 0039 ADD R12 R12 K52 - 0x00301806, // 003A ADD R12 R12 R6 - 0x7C2C0200, // 003B CALL R11 1 - 0x80001600, // 003C RET 0 - 0x4C2C0000, // 003D LDNIL R11 - 0x60300009, // 003E GETGBL R12 G9 - 0x8C340307, // 003F GETMET R13 R1 K7 - 0x583C0035, // 0040 LDCONST R15 K53 - 0x7C340400, // 0041 CALL R13 2 - 0x7C300200, // 0042 CALL R12 1 - 0x4C340000, // 0043 LDNIL R13 - 0x4C380000, // 0044 LDNIL R14 - 0x2038180E, // 0045 NE R14 R12 R14 - 0x783A0007, // 0046 JMPF R14 #004F - 0x8C381136, // 0047 GETMET R14 R8 K54 - 0x5C401800, // 0048 MOVE R16 R12 - 0x7C380400, // 0049 CALL R14 2 - 0x5C341C00, // 004A MOVE R13 R14 - 0x4C380000, // 004B LDNIL R14 - 0x20381A0E, // 004C NE R14 R13 R14 - 0x783A0000, // 004D JMPF R14 #004F - 0x882C1B14, // 004E GETMBR R11 R13 K20 - 0x4C380000, // 004F LDNIL R14 - 0x1C38160E, // 0050 EQ R14 R11 R14 - 0x783A0002, // 0051 JMPF R14 #0055 - 0x8C381137, // 0052 GETMET R14 R8 K55 - 0x7C380200, // 0053 CALL R14 1 - 0x5C2C1C00, // 0054 MOVE R11 R14 - 0x8C380929, // 0055 GETMET R14 R4 K41 - 0x5C400000, // 0056 MOVE R16 R0 - 0x00467006, // 0057 ADD R17 K56 R6 - 0x7C380600, // 0058 CALL R14 3 - 0x4C3C0000, // 0059 LDNIL R15 - 0x4C400000, // 005A LDNIL R16 - 0x1C401C10, // 005B EQ R16 R14 R16 - 0x78420010, // 005C JMPF R16 #006E - 0x8C400929, // 005D GETMET R16 R4 K41 - 0x5C480600, // 005E MOVE R18 R3 - 0x5C4C0C00, // 005F MOVE R19 R6 - 0x7C400600, // 0060 CALL R16 3 - 0x4C440000, // 0061 LDNIL R17 - 0x20442011, // 0062 NE R17 R16 R17 - 0x78460009, // 0063 JMPF R17 #006E - 0x60440004, // 0064 GETGBL R17 G4 - 0x5C482000, // 0065 MOVE R18 R16 - 0x7C440200, // 0066 CALL R17 1 - 0x1C442339, // 0067 EQ R17 R17 K57 - 0x78460004, // 0068 JMPF R17 #006E - 0x5C442000, // 0069 MOVE R17 R16 - 0x5C481600, // 006A MOVE R18 R11 - 0x7C440200, // 006B CALL R17 1 - 0x5C3C2200, // 006C MOVE R15 R17 - 0x8838013A, // 006D GETMBR R14 R0 K58 - 0x4C400000, // 006E LDNIL R16 - 0x1C401C10, // 006F EQ R16 R14 R16 - 0x7842000F, // 0070 JMPF R16 #0081 - 0x8C40093B, // 0071 GETMET R16 R4 K59 - 0x5C480C00, // 0072 MOVE R18 R6 - 0x7C400400, // 0073 CALL R16 2 - 0x4C440000, // 0074 LDNIL R17 - 0x20442011, // 0075 NE R17 R16 R17 - 0x78460009, // 0076 JMPF R17 #0081 - 0x60440004, // 0077 GETGBL R17 G4 - 0x5C482000, // 0078 MOVE R18 R16 - 0x7C440200, // 0079 CALL R17 1 - 0x1C442339, // 007A EQ R17 R17 K57 - 0x78460004, // 007B JMPF R17 #0081 - 0x5C442000, // 007C MOVE R17 R16 - 0x5C481600, // 007D MOVE R18 R11 - 0x7C440200, // 007E CALL R17 1 - 0x5C3C2200, // 007F MOVE R15 R17 - 0x8838013A, // 0080 GETMBR R14 R0 K58 - 0x4C400000, // 0081 LDNIL R16 - 0x1C401C10, // 0082 EQ R16 R14 R16 - 0x78420006, // 0083 JMPF R16 #008B - 0x60400001, // 0084 GETGBL R16 G1 - 0x60440008, // 0085 GETGBL R17 G8 - 0x5C480C00, // 0086 MOVE R18 R6 - 0x7C440200, // 0087 CALL R17 1 - 0x00467811, // 0088 ADD R17 K60 R17 - 0x7C400200, // 0089 CALL R16 1 - 0x80002000, // 008A RET 0 - 0x5C401C00, // 008B MOVE R16 R14 - 0x5C441600, // 008C MOVE R17 R11 - 0x5C480400, // 008D MOVE R18 R2 - 0x5C4C0200, // 008E MOVE R19 R1 - 0x5C501E00, // 008F MOVE R20 R15 - 0x5C541A00, // 0090 MOVE R21 R13 - 0x7C400A00, // 0091 CALL R16 5 - 0x5C1C2000, // 0092 MOVE R7 R16 - 0x8C40113D, // 0093 GETMET R16 R8 K61 - 0x5C480A00, // 0094 MOVE R18 R5 - 0x5C4C0E00, // 0095 MOVE R19 R7 - 0x7C400600, // 0096 CALL R16 3 - 0x4C2C0000, // 0097 LDNIL R11 - 0x202C140B, // 0098 NE R11 R10 R11 - 0x782E0018, // 0099 JMPF R11 #00B3 - 0xA802000B, // 009A EXBLK 0 #00A7 - 0x5C2C1400, // 009B MOVE R11 R10 - 0x7C2C0000, // 009C CALL R11 0 - 0x60300004, // 009D GETGBL R12 G4 - 0x5C341600, // 009E MOVE R13 R11 - 0x7C300200, // 009F CALL R12 1 - 0x1C30193E, // 00A0 EQ R12 R12 K62 - 0x78320002, // 00A1 JMPF R12 #00A5 - 0x5C301600, // 00A2 MOVE R12 R11 - 0x5C340E00, // 00A3 MOVE R13 R7 - 0x7C300200, // 00A4 CALL R12 1 - 0xA8040001, // 00A5 EXBLK 1 1 - 0x7002000B, // 00A6 JMP #00B3 - 0xAC2C0002, // 00A7 CATCH R11 0 2 - 0x70020008, // 00A8 JMP #00B2 - 0x60340001, // 00A9 GETGBL R13 G1 - 0x60380018, // 00AA GETGBL R14 G24 - 0x583C003F, // 00AB LDCONST R15 K63 - 0x5C401200, // 00AC MOVE R16 R9 - 0x5C441600, // 00AD MOVE R17 R11 - 0x5C481800, // 00AE MOVE R18 R12 - 0x7C380800, // 00AF CALL R14 4 - 0x7C340200, // 00B0 CALL R13 1 - 0x70020000, // 00B1 JMP #00B3 - 0xB0080000, // 00B2 RAISE 2 R0 R0 - 0x4C2C0000, // 00B3 LDNIL R11 - 0x1C2C0A0B, // 00B4 EQ R11 R5 R11 - 0x782E0000, // 00B5 JMPF R11 #00B7 - 0x80001600, // 00B6 RET 0 - 0x1C2C0B00, // 00B7 EQ R11 R5 K0 - 0x782E0005, // 00B8 JMPF R11 #00BF - 0x202C0D31, // 00B9 NE R11 R6 K49 - 0x782E0003, // 00BA JMPF R11 #00BF - 0x602C0001, // 00BB GETGBL R11 G1 - 0x58300040, // 00BC LDCONST R12 K64 - 0x7C2C0200, // 00BD CALL R11 1 - 0x80001600, // 00BE RET 0 - 0x1C2C0B00, // 00BF EQ R11 R5 K0 - 0x782E0005, // 00C0 JMPF R11 #00C7 - 0x8C2C012F, // 00C1 GETMET R11 R0 K47 - 0x7C2C0200, // 00C2 CALL R11 1 - 0x8C2C1736, // 00C3 GETMET R11 R11 K54 - 0x58340000, // 00C4 LDCONST R13 K0 - 0x7C2C0400, // 00C5 CALL R11 2 - 0x5C1C1600, // 00C6 MOVE R7 R11 - 0x602C0010, // 00C7 GETGBL R11 G16 - 0x8C300303, // 00C8 GETMET R12 R1 K3 - 0x7C300200, // 00C9 CALL R12 1 - 0x7C2C0200, // 00CA CALL R11 1 - 0xA8020004, // 00CB EXBLK 0 #00D1 - 0x5C301600, // 00CC MOVE R12 R11 - 0x7C300000, // 00CD CALL R12 0 - 0x9434020C, // 00CE GETIDX R13 R1 R12 - 0x901C180D, // 00CF SETMBR R7 R12 R13 - 0x7001FFFA, // 00D0 JMP #00CC - 0x582C0005, // 00D1 LDCONST R11 K5 - 0xAC2C0200, // 00D2 CATCH R11 1 0 - 0xB0080000, // 00D3 RAISE 2 R0 R0 - 0x8C2C0F41, // 00D4 GETMET R11 R7 K65 - 0x7C2C0200, // 00D5 CALL R11 1 - 0x80000000, // 00D6 RET 0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: _load ********************************************************************/ @@ -11449,103 +11271,103 @@ be_local_closure(class_HASPmota__load, /* name */ be_str_weak(_load), &be_const_str_solidified, ( &(const binstruction[99]) { /* code */ - 0xA40A8400, // 0000 IMPORT R2 K66 - 0xA40E2E00, // 0001 IMPORT R3 K23 + 0xA40A5A00, // 0000 IMPORT R2 K45 + 0xA40E0C00, // 0001 IMPORT R3 K6 0x60100011, // 0002 GETGBL R4 G17 0x5C140200, // 0003 MOVE R5 R1 - 0x58180043, // 0004 LDCONST R6 K67 + 0x5818002E, // 0004 LDCONST R6 K46 0x7C100400, // 0005 CALL R4 2 - 0x8C140944, // 0006 GETMET R5 R4 K68 + 0x8C14092F, // 0006 GETMET R5 R4 K47 0x7C140200, // 0007 CALL R5 1 - 0x8C180945, // 0008 GETMET R6 R4 K69 + 0x8C180930, // 0008 GETMET R6 R4 K48 0x7C180200, // 0009 CALL R6 1 - 0x8C180546, // 000A GETMET R6 R2 K70 + 0x8C180531, // 000A GETMET R6 R2 K49 0x5C200A00, // 000B MOVE R8 R5 - 0x58240047, // 000C LDCONST R9 K71 + 0x58240032, // 000C LDCONST R9 K50 0x7C180600, // 000D CALL R6 3 0x4C100000, // 000E LDNIL R4 0x4C140000, // 000F LDNIL R5 0x601C000C, // 0010 GETGBL R7 G12 0x5C200C00, // 0011 MOVE R8 R6 0x7C1C0200, // 0012 CALL R7 1 - 0x241C0F00, // 0013 GT R7 R7 K0 + 0x241C0F0F, // 0013 GT R7 R7 K15 0x781E0039, // 0014 JMPF R7 #004F - 0x8C1C0718, // 0015 GETMET R7 R3 K24 - 0x94240D00, // 0016 GETIDX R9 R6 K0 + 0x8C1C0707, // 0015 GETMET R7 R3 K7 + 0x94240D0F, // 0016 GETIDX R9 R6 K15 0x7C1C0400, // 0017 CALL R7 2 0x60200004, // 0018 GETGBL R8 G4 0x5C240E00, // 0019 MOVE R9 R7 0x7C200200, // 001A CALL R8 1 - 0x1C201119, // 001B EQ R8 R8 K25 + 0x1C201108, // 001B EQ R8 R8 K8 0x7822001B, // 001C JMPF R8 #0039 - 0xB8229000, // 001D GETNGBL R8 K72 - 0x8C201149, // 001E GETMET R8 R8 K73 + 0xB8226600, // 001D GETNGBL R8 K51 + 0x8C201134, // 001E GETMET R8 R8 K52 0x542A0003, // 001F LDINT R10 4 0x7C200400, // 0020 CALL R8 2 0x78220007, // 0021 JMPF R8 #002A - 0xB8229000, // 0022 GETNGBL R8 K72 - 0x8C20114A, // 0023 GETMET R8 R8 K74 + 0xB8226600, // 0022 GETNGBL R8 K51 + 0x8C201135, // 0023 GETMET R8 R8 K53 0x60280018, // 0024 GETGBL R10 G24 - 0x582C004B, // 0025 LDCONST R11 K75 - 0x94300D00, // 0026 GETIDX R12 R6 K0 + 0x582C0036, // 0025 LDCONST R11 K54 + 0x94300D0F, // 0026 GETIDX R12 R6 K15 0x7C280400, // 0027 CALL R10 2 0x542E0003, // 0028 LDINT R11 4 0x7C200600, // 0029 CALL R8 3 - 0x8C20011A, // 002A GETMET R8 R0 K26 + 0x8C200109, // 002A GETMET R8 R0 K9 0x5C280E00, // 002B MOVE R10 R7 0x7C200400, // 002C CALL R8 2 - 0x88200102, // 002D GETMBR R8 R0 K2 + 0x8820010B, // 002D GETMBR R8 R0 K11 0x4C240000, // 002E LDNIL R9 0x1C201009, // 002F EQ R8 R8 R9 0x78220000, // 0030 JMPF R8 #0032 - 0xB006394C, // 0031 RAISE 1 K28 K76 - 0x8C20011B, // 0032 GETMET R8 R0 K27 + 0xB0061B37, // 0031 RAISE 1 K13 K55 + 0x8C20010A, // 0032 GETMET R8 R0 K10 0x5C280E00, // 0033 MOVE R10 R7 - 0x882C0102, // 0034 GETMBR R11 R0 K2 - 0x88300101, // 0035 GETMBR R12 R0 K1 + 0x882C010B, // 0034 GETMBR R11 R0 K11 + 0x8830010C, // 0035 GETMBR R12 R0 K12 0x942C160C, // 0036 GETIDX R11 R11 R12 0x7C200600, // 0037 CALL R8 3 0x70020010, // 0038 JMP #004A 0x6020000C, // 0039 GETGBL R8 G12 - 0x8C24054D, // 003A GETMET R9 R2 K77 - 0x942C0D00, // 003B GETIDX R11 R6 K0 - 0x5830004E, // 003C LDCONST R12 K78 - 0x5834004F, // 003D LDCONST R13 K79 + 0x8C240538, // 003A GETMET R9 R2 K56 + 0x942C0D0F, // 003B GETIDX R11 R6 K15 + 0x58300039, // 003C LDCONST R12 K57 + 0x5834003A, // 003D LDCONST R13 K58 0x7C240800, // 003E CALL R9 4 0x7C200200, // 003F CALL R8 1 - 0x24201100, // 0040 GT R8 R8 K0 + 0x2420110F, // 0040 GT R8 R8 K15 0x78220007, // 0041 JMPF R8 #004A - 0xB8229000, // 0042 GETNGBL R8 K72 - 0x8C20114A, // 0043 GETMET R8 R8 K74 + 0xB8226600, // 0042 GETNGBL R8 K51 + 0x8C201135, // 0043 GETMET R8 R8 K53 0x60280018, // 0044 GETGBL R10 G24 - 0x582C0050, // 0045 LDCONST R11 K80 - 0x94300D00, // 0046 GETIDX R12 R6 K0 + 0x582C003B, // 0045 LDCONST R11 K59 + 0x94300D0F, // 0046 GETIDX R12 R6 K15 0x7C280400, // 0047 CALL R10 2 - 0x582C0051, // 0048 LDCONST R11 K81 + 0x582C003C, // 0048 LDCONST R11 K60 0x7C200600, // 0049 CALL R8 3 0x4C1C0000, // 004A LDNIL R7 - 0x8C200D52, // 004B GETMET R8 R6 K82 - 0x58280000, // 004C LDCONST R10 K0 + 0x8C200D3D, // 004B GETMET R8 R6 K61 + 0x5828000F, // 004C LDCONST R10 K15 0x7C200400, // 004D CALL R8 2 0x7001FFC0, // 004E JMP #0010 0x4C180000, // 004F LDNIL R6 - 0x8C1C0109, // 0050 GETMET R7 R0 K9 + 0x8C1C013E, // 0050 GETMET R7 R0 K62 0x4C240000, // 0051 LDNIL R9 0x7C1C0400, // 0052 CALL R7 2 0x6020000C, // 0053 GETGBL R8 G12 0x5C240E00, // 0054 MOVE R9 R7 0x7C200200, // 0055 CALL R8 1 - 0x1C201100, // 0056 EQ R8 R8 K0 + 0x1C20110F, // 0056 EQ R8 R8 K15 0x78220000, // 0057 JMPF R8 #0059 - 0xB0063953, // 0058 RAISE 1 K28 K83 - 0x94200F00, // 0059 GETIDX R8 R7 K0 - 0x90020208, // 005A SETMBR R0 K1 R8 - 0x88200102, // 005B GETMBR R8 R0 K2 - 0x88240101, // 005C GETMBR R9 R0 K1 + 0xB0061B3F, // 0058 RAISE 1 K13 K63 + 0x94200F0F, // 0059 GETIDX R8 R7 K15 + 0x90021808, // 005A SETMBR R0 K12 R8 + 0x8820010B, // 005B GETMBR R8 R0 K11 + 0x8824010C, // 005C GETMBR R9 R0 K12 0x94201009, // 005D GETIDX R8 R8 R9 - 0x8C20110F, // 005E GETMET R8 R8 K15 - 0x58280000, // 005F LDCONST R10 K0 - 0x582C0000, // 0060 LDCONST R11 K0 + 0x8C201140, // 005E GETMET R8 R8 K64 + 0x5828000F, // 005F LDCONST R10 K15 + 0x582C000F, // 0060 LDCONST R11 K15 0x7C200600, // 0061 CALL R8 3 0x80000000, // 0062 RET 0 }) @@ -11571,34 +11393,34 @@ be_local_closure(class_HASPmota_page_dir_to, /* name */ be_str_weak(page_dir_to), &be_const_str_solidified, ( &(const binstruction[32]) { /* code */ - 0x8C080109, // 0000 GETMET R2 R0 K9 - 0x58100000, // 0001 LDCONST R4 K0 + 0x8C08013E, // 0000 GETMET R2 R0 K62 + 0x5810000F, // 0001 LDCONST R4 K15 0x7C080400, // 0002 CALL R2 2 0x4C0C0000, // 0003 LDNIL R3 0x1C0C0403, // 0004 EQ R3 R2 R3 0x780E0000, // 0005 JMPF R3 #0007 - 0x80060000, // 0006 RET 1 K0 + 0x80061E00, // 0006 RET 1 K15 0x600C000C, // 0007 GETGBL R3 G12 0x5C100400, // 0008 MOVE R4 R2 0x7C0C0200, // 0009 CALL R3 1 - 0x18100708, // 000A LE R4 R3 K8 + 0x18100715, // 000A LE R4 R3 K21 0x78120000, // 000B JMPF R4 #000D - 0x80060000, // 000C RET 1 K0 - 0x1C100751, // 000D EQ R4 R3 K81 + 0x80061E00, // 000C RET 1 K15 + 0x1C10073C, // 000D EQ R4 R3 K60 0x78120000, // 000E JMPF R4 #0010 - 0x80061000, // 000F RET 1 K8 - 0x8C100507, // 0010 GETMET R4 R2 K7 + 0x80062A00, // 000F RET 1 K21 + 0x8C100514, // 0010 GETMET R4 R2 K20 0x5C180200, // 0011 MOVE R6 R1 0x7C100400, // 0012 CALL R4 2 0x4C140000, // 0013 LDNIL R5 0x1C140805, // 0014 EQ R5 R4 R5 0x78160000, // 0015 JMPF R5 #0017 - 0x80060000, // 0016 RET 1 K0 - 0x00140708, // 0017 ADD R5 R3 K8 - 0x0C140B51, // 0018 DIV R5 R5 K81 + 0x80061E00, // 0016 RET 1 K15 + 0x00140715, // 0017 ADD R5 R3 K21 + 0x0C140B3C, // 0018 DIV R5 R5 K60 0x18140805, // 0019 LE R5 R4 R5 0x78160001, // 001A JMPF R5 #001D - 0x80061000, // 001B RET 1 K8 + 0x80062A00, // 001B RET 1 K21 0x70020001, // 001C JMP #001F 0x5415FFFE, // 001D LDINT R5 -1 0x80040A00, // 001E RET 1 R5 @@ -11610,43 +11432,11 @@ be_local_closure(class_HASPmota_page_dir_to, /* name */ /******************************************************************** -** Solidified function: do_action +** Solidified function: page_show ********************************************************************/ -be_local_closure(class_HASPmota_do_action, /* name */ +be_local_closure(class_HASPmota_page_show, /* name */ be_nested_proto( - 6, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(do_action), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0xB80E4000, // 0000 GETNGBL R3 K32 - 0x880C0754, // 0001 GETMBR R3 R3 K84 - 0x200C0403, // 0002 NE R3 R2 R3 - 0x780E0000, // 0003 JMPF R3 #0005 - 0x80000600, // 0004 RET 0 - 0x8C0C0155, // 0005 GETMET R3 R0 K85 - 0x88140356, // 0006 GETMBR R5 R1 K86 - 0x7C0C0400, // 0007 CALL R3 2 - 0x80000000, // 0008 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: parse_page -********************************************************************/ -be_local_closure(class_HASPmota_parse_page, /* name */ - be_nested_proto( - 9, /* nstack */ + 8, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -11655,143 +11445,80 @@ be_local_closure(class_HASPmota_parse_page, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(parse_page), + be_str_weak(page_show), &be_const_str_solidified, - ( &(const binstruction[54]) { /* code */ - 0x8C080357, // 0000 GETMET R2 R1 K87 - 0x58100058, // 0001 LDCONST R4 K88 - 0x7C080400, // 0002 CALL R2 2 - 0x780A0030, // 0003 JMPF R2 #0035 - 0x60080004, // 0004 GETGBL R2 G4 - 0x940C0358, // 0005 GETIDX R3 R1 K88 - 0x7C080200, // 0006 CALL R2 1 - 0x1C08052B, // 0007 EQ R2 R2 K43 - 0x780A002B, // 0008 JMPF R2 #0035 - 0x60080009, // 0009 GETGBL R2 G9 - 0x940C0358, // 000A GETIDX R3 R1 K88 - 0x7C080200, // 000B CALL R2 1 - 0x90020202, // 000C SETMBR R0 K1 R2 - 0x880C0102, // 000D GETMBR R3 R0 K2 - 0x8C0C0759, // 000E GETMET R3 R3 K89 - 0x5C140400, // 000F MOVE R5 R2 - 0x7C0C0400, // 0010 CALL R3 2 - 0x740E0006, // 0011 JMPT R3 #0019 - 0x880C015A, // 0012 GETMBR R3 R0 K90 - 0x88100102, // 0013 GETMBR R4 R0 K2 - 0x5C140600, // 0014 MOVE R5 R3 - 0x5C180400, // 0015 MOVE R6 R2 - 0x5C1C0000, // 0016 MOVE R7 R0 - 0x7C140400, // 0017 CALL R5 2 - 0x98100405, // 0018 SETIDX R4 R2 R5 - 0x8C0C0307, // 0019 GETMET R3 R1 K7 - 0x5814002D, // 001A LDCONST R5 K45 - 0x7C0C0400, // 001B CALL R3 2 - 0x1C0C0700, // 001C EQ R3 R3 K0 - 0x780E0016, // 001D JMPF R3 #0035 - 0x8C0C012F, // 001E GETMET R3 R0 K47 - 0x7C0C0200, // 001F CALL R3 1 - 0x60100009, // 0020 GETGBL R4 G9 - 0x8C140307, // 0021 GETMET R5 R1 K7 - 0x581C000A, // 0022 LDCONST R7 K10 - 0x4C200000, // 0023 LDNIL R8 - 0x7C140600, // 0024 CALL R5 3 - 0x7C100200, // 0025 CALL R4 1 - 0x900E1404, // 0026 SETMBR R3 K10 R4 - 0x60100009, // 0027 GETGBL R4 G9 - 0x8C140307, // 0028 GETMET R5 R1 K7 - 0x581C000B, // 0029 LDCONST R7 K11 - 0x4C200000, // 002A LDNIL R8 - 0x7C140600, // 002B CALL R5 3 - 0x7C100200, // 002C CALL R4 1 - 0x900E1604, // 002D SETMBR R3 K11 R4 - 0x60100009, // 002E GETGBL R4 G9 - 0x8C140307, // 002F GETMET R5 R1 K7 - 0x581C000C, // 0030 LDCONST R7 K12 - 0x4C200000, // 0031 LDNIL R8 - 0x7C140600, // 0032 CALL R5 3 - 0x7C100200, // 0033 CALL R4 1 - 0x900E1804, // 0034 SETMBR R3 K12 R4 - 0x80000000, // 0035 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: sort -********************************************************************/ -be_local_closure(class_HASPmota_sort, /* name */ - be_nested_proto( - 7, /* nstack */ - 1, /* argc */ - 12, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(sort), - &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x58040028, // 0000 LDCONST R1 K40 - 0x60080010, // 0001 GETGBL R2 G16 - 0x600C000C, // 0002 GETGBL R3 G12 - 0x5C100000, // 0003 MOVE R4 R0 - 0x7C0C0200, // 0004 CALL R3 1 - 0x040C0708, // 0005 SUB R3 R3 K8 - 0x400E1003, // 0006 CONNECT R3 K8 R3 - 0x7C080200, // 0007 CALL R2 1 - 0xA8020010, // 0008 EXBLK 0 #001A - 0x5C0C0400, // 0009 MOVE R3 R2 - 0x7C0C0000, // 000A CALL R3 0 - 0x94100003, // 000B GETIDX R4 R0 R3 - 0x5C140600, // 000C MOVE R5 R3 - 0x24180B00, // 000D GT R6 R5 K0 - 0x781A0008, // 000E JMPF R6 #0018 - 0x04180B08, // 000F SUB R6 R5 K8 - 0x94180006, // 0010 GETIDX R6 R0 R6 - 0x24180C04, // 0011 GT R6 R6 R4 - 0x781A0004, // 0012 JMPF R6 #0018 - 0x04180B08, // 0013 SUB R6 R5 K8 - 0x94180006, // 0014 GETIDX R6 R0 R6 - 0x98000A06, // 0015 SETIDX R0 R5 R6 - 0x04140B08, // 0016 SUB R5 R5 K8 - 0x7001FFF4, // 0017 JMP #000D - 0x98000A04, // 0018 SETIDX R0 R5 R4 - 0x7001FFEE, // 0019 JMP #0009 - 0x58080005, // 001A LDCONST R2 K5 - 0xAC080200, // 001B CATCH R2 1 0 - 0xB0080000, // 001C RAISE 2 R0 R0 - 0x80040000, // 001D RET 1 R0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_page_cur -********************************************************************/ -be_local_closure(class_HASPmota_get_page_cur, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(get_page_cur), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x94040202, // 0002 GETIDX R1 R1 R2 - 0x80040200, // 0003 RET 1 R1 + ( &(const binstruction[71]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x880C010B, // 0001 GETMBR R3 R0 K11 + 0x8810010C, // 0002 GETMBR R4 R0 K12 + 0x940C0604, // 0003 GETIDX R3 R3 R4 + 0x8C10013E, // 0004 GETMET R4 R0 K62 + 0x8818010C, // 0005 GETMBR R6 R0 K12 + 0x7C100400, // 0006 CALL R4 2 + 0x6014000C, // 0007 GETGBL R5 G12 + 0x5C180800, // 0008 MOVE R6 R4 + 0x7C140200, // 0009 CALL R5 1 + 0x18140B15, // 000A LE R5 R5 K21 + 0x78160000, // 000B JMPF R5 #000D + 0x80000A00, // 000C RET 0 + 0x1C140321, // 000D EQ R5 R1 K33 + 0x78160009, // 000E JMPF R5 #0019 + 0x60140009, // 000F GETGBL R5 G9 + 0x88180721, // 0010 GETMBR R6 R3 K33 + 0x7C140200, // 0011 CALL R5 1 + 0x5C080A00, // 0012 MOVE R2 R5 + 0x4C140000, // 0013 LDNIL R5 + 0x1C140405, // 0014 EQ R5 R2 R5 + 0x78160001, // 0015 JMPF R5 #0018 + 0x5415FFFE, // 0016 LDINT R5 -1 + 0x94080805, // 0017 GETIDX R2 R4 R5 + 0x70020023, // 0018 JMP #003D + 0x1C140322, // 0019 EQ R5 R1 K34 + 0x78160008, // 001A JMPF R5 #0024 + 0x60140009, // 001B GETGBL R5 G9 + 0x88180722, // 001C GETMBR R6 R3 K34 + 0x7C140200, // 001D CALL R5 1 + 0x5C080A00, // 001E MOVE R2 R5 + 0x4C140000, // 001F LDNIL R5 + 0x1C140405, // 0020 EQ R5 R2 R5 + 0x78160000, // 0021 JMPF R5 #0023 + 0x94080915, // 0022 GETIDX R2 R4 K21 + 0x70020018, // 0023 JMP #003D + 0x1C140323, // 0024 EQ R5 R1 K35 + 0x7816000B, // 0025 JMPF R5 #0032 + 0x60140009, // 0026 GETGBL R5 G9 + 0x88180723, // 0027 GETMBR R6 R3 K35 + 0x7C140200, // 0028 CALL R5 1 + 0x5C080A00, // 0029 MOVE R2 R5 + 0x4C140000, // 002A LDNIL R5 + 0x1C140405, // 002B EQ R5 R2 R5 + 0x78160003, // 002C JMPF R5 #0031 + 0x8C14013E, // 002D GETMET R5 R0 K62 + 0x4C1C0000, // 002E LDNIL R7 + 0x7C140400, // 002F CALL R5 2 + 0x94080B0F, // 0030 GETIDX R2 R5 K15 + 0x7002000A, // 0031 JMP #003D + 0x88140118, // 0032 GETMBR R5 R0 K24 + 0x8C140B41, // 0033 GETMET R5 R5 K65 + 0x5C1C0200, // 0034 MOVE R7 R1 + 0x7C140400, // 0035 CALL R5 2 + 0x78160005, // 0036 JMPF R5 #003D + 0x60140009, // 0037 GETGBL R5 G9 + 0x5419FFFE, // 0038 LDINT R6 -1 + 0x401A2A06, // 0039 CONNECT R6 K21 R6 + 0x94180206, // 003A GETIDX R6 R1 R6 + 0x7C140200, // 003B CALL R5 1 + 0x5C080A00, // 003C MOVE R2 R5 + 0x4C140000, // 003D LDNIL R5 + 0x20140405, // 003E NE R5 R2 R5 + 0x78160005, // 003F JMPF R5 #0046 + 0x2414050F, // 0040 GT R5 R2 K15 + 0x78160003, // 0041 JMPF R5 #0046 + 0x8814010B, // 0042 GETMBR R5 R0 K11 + 0x94140A02, // 0043 GETIDX R5 R5 R2 + 0x8C140B40, // 0044 GETMET R5 R5 K64 + 0x7C140200, // 0045 CALL R5 1 + 0x80000000, // 0046 RET 0 }) ) ); @@ -11815,108 +11542,108 @@ be_local_closure(class_HASPmota_start, /* name */ be_str_weak(start), &be_const_str_solidified, ( &(const binstruction[105]) { /* code */ - 0xA40EB600, // 0000 IMPORT R3 K91 + 0xA40E8400, // 0000 IMPORT R3 K66 0x4C100000, // 0001 LDNIL R4 0x1C100404, // 0002 EQ R4 R2 R4 0x78120000, // 0003 JMPF R4 #0005 - 0x8808015C, // 0004 GETMBR R2 R0 K92 - 0x8C10075D, // 0005 GETMET R4 R3 K93 + 0x88080143, // 0004 GETMBR R2 R0 K67 + 0x8C100744, // 0005 GETMET R4 R3 K68 0x5C180400, // 0006 MOVE R6 R2 0x7C100400, // 0007 CALL R4 2 0x74120002, // 0008 JMPT R4 #000C - 0x0012BC02, // 0009 ADD R4 K94 R2 - 0x0010095F, // 000A ADD R4 R4 K95 - 0xB006C004, // 000B RAISE 1 K96 R4 - 0xB8124000, // 000C GETNGBL R4 K32 - 0x8C100961, // 000D GETMET R4 R4 K97 + 0x00128A02, // 0009 ADD R4 K69 R2 + 0x00100946, // 000A ADD R4 R4 K70 + 0xB0068E04, // 000B RAISE 1 K71 R4 + 0xB8120600, // 000C GETNGBL R4 K3 + 0x8C100948, // 000D GETMET R4 R4 K72 0x7C100200, // 000E CALL R4 1 0x60100017, // 000F GETGBL R4 G23 0x5C140200, // 0010 MOVE R5 R1 0x7C100200, // 0011 CALL R4 1 - 0x9002C404, // 0012 SETMBR R0 K98 R4 - 0xB8124000, // 0013 GETNGBL R4 K32 - 0x8C100964, // 0014 GETMET R4 R4 K100 + 0x90029204, // 0012 SETMBR R0 K73 R4 + 0xB8120600, // 0013 GETNGBL R4 K3 + 0x8C10094B, // 0014 GETMET R4 R4 K75 0x7C100200, // 0015 CALL R4 1 - 0x9002C604, // 0016 SETMBR R0 K99 R4 - 0xB8124000, // 0017 GETNGBL R4 K32 - 0x8C100966, // 0018 GETMET R4 R4 K102 + 0x90029404, // 0016 SETMBR R0 K74 R4 + 0xB8120600, // 0017 GETNGBL R4 K3 + 0x8C10094D, // 0018 GETMET R4 R4 K77 0x7C100200, // 0019 CALL R4 1 - 0x9002CA04, // 001A SETMBR R0 K101 R4 - 0xB8124000, // 001B GETNGBL R4 K32 - 0x8C100968, // 001C GETMET R4 R4 K104 + 0x90029804, // 001A SETMBR R0 K76 R4 + 0xB8120600, // 001B GETNGBL R4 K3 + 0x8C10094F, // 001C GETMET R4 R4 K79 0x7C100200, // 001D CALL R4 1 - 0x9002CE04, // 001E SETMBR R0 K103 R4 + 0x90029C04, // 001E SETMBR R0 K78 R4 0xA8020007, // 001F EXBLK 0 #0028 - 0xB8124000, // 0020 GETNGBL R4 K32 - 0x8C10096A, // 0021 GETMET R4 R4 K106 - 0x5818006B, // 0022 LDCONST R6 K107 + 0xB8120600, // 0020 GETNGBL R4 K3 + 0x8C100951, // 0021 GETMET R4 R4 K81 + 0x58180052, // 0022 LDCONST R6 K82 0x541E000F, // 0023 LDINT R7 16 0x7C100600, // 0024 CALL R4 3 - 0x9002D204, // 0025 SETMBR R0 K105 R4 + 0x9002A004, // 0025 SETMBR R0 K80 R4 0xA8040001, // 0026 EXBLK 1 1 0x70020009, // 0027 JMP #0032 0xAC100000, // 0028 CATCH R4 0 0 0x70020006, // 0029 JMP #0031 - 0xB8124000, // 002A GETNGBL R4 K32 - 0x8C10096A, // 002B GETMET R4 R4 K106 - 0x5818006C, // 002C LDCONST R6 K108 + 0xB8120600, // 002A GETNGBL R4 K3 + 0x8C100951, // 002B GETMET R4 R4 K81 + 0x58180053, // 002C LDCONST R6 K83 0x541E000D, // 002D LDINT R7 14 0x7C100600, // 002E CALL R4 3 - 0x9002D204, // 002F SETMBR R0 K105 R4 + 0x9002A004, // 002F SETMBR R0 K80 R4 0x70020000, // 0030 JMP #0032 0xB0080000, // 0031 RAISE 2 R0 R0 - 0xB8124000, // 0032 GETNGBL R4 K32 - 0x8C10096D, // 0033 GETMET R4 R4 K109 - 0x58180000, // 0034 LDCONST R6 K0 - 0xB81E4000, // 0035 GETNGBL R7 K32 - 0x8C1C0F6E, // 0036 GETMET R7 R7 K110 - 0x5824006F, // 0037 LDCONST R9 K111 + 0xB8120600, // 0032 GETNGBL R4 K3 + 0x8C100954, // 0033 GETMET R4 R4 K84 + 0x5818000F, // 0034 LDCONST R6 K15 + 0xB81E0600, // 0035 GETNGBL R7 K3 + 0x8C1C0F55, // 0036 GETMET R7 R7 K85 + 0x58240056, // 0037 LDCONST R9 K86 0x7C1C0400, // 0038 CALL R7 2 - 0xB8224000, // 0039 GETNGBL R8 K32 - 0x8C20116E, // 003A GETMET R8 R8 K110 - 0x58280070, // 003B LDCONST R10 K112 + 0xB8220600, // 0039 GETNGBL R8 K3 + 0x8C201155, // 003A GETMET R8 R8 K85 + 0x58280057, // 003B LDCONST R10 K87 0x7C200400, // 003C CALL R8 2 - 0x88240162, // 003D GETMBR R9 R0 K98 - 0x88280169, // 003E GETMBR R10 R0 K105 + 0x88240149, // 003D GETMBR R9 R0 K73 + 0x88280150, // 003E GETMBR R10 R0 K80 0x7C100C00, // 003F CALL R4 6 - 0x88140167, // 0040 GETMBR R5 R0 K103 - 0x8C140B71, // 0041 GETMET R5 R5 K113 + 0x8814014E, // 0040 GETMBR R5 R0 K78 + 0x8C140B58, // 0041 GETMET R5 R5 K88 0x7C140200, // 0042 CALL R5 1 - 0x8C140B72, // 0043 GETMET R5 R5 K114 + 0x8C140B59, // 0043 GETMET R5 R5 K89 0x5C1C0800, // 0044 MOVE R7 R4 0x7C140400, // 0045 CALL R5 2 - 0x88140167, // 0046 GETMBR R5 R0 K103 - 0x8C140B73, // 0047 GETMET R5 R5 K115 - 0x881C0162, // 0048 GETMBR R7 R0 K98 + 0x8814014E, // 0046 GETMBR R5 R0 K78 + 0x8C140B5A, // 0047 GETMET R5 R5 K90 + 0x881C0149, // 0048 GETMBR R7 R0 K73 0x781E0004, // 0049 JMPF R7 #004F - 0xB81E4000, // 004A GETNGBL R7 K32 - 0x8C1C0F6E, // 004B GETMET R7 R7 K110 - 0x58240000, // 004C LDCONST R9 K0 + 0xB81E0600, // 004A GETNGBL R7 K3 + 0x8C1C0F55, // 004B GETMET R7 R7 K85 + 0x5824000F, // 004C LDCONST R9 K15 0x7C1C0400, // 004D CALL R7 2 0x70020003, // 004E JMP #0053 - 0xB81E4000, // 004F GETNGBL R7 K32 - 0x8C1C0F6E, // 0050 GETMET R7 R7 K110 - 0x58240074, // 0051 LDCONST R9 K116 + 0xB81E0600, // 004F GETNGBL R7 K3 + 0x8C1C0F55, // 0050 GETMET R7 R7 K85 + 0x5824005B, // 0051 LDCONST R9 K91 0x7C1C0400, // 0052 CALL R7 2 - 0x58200000, // 0053 LDCONST R8 K0 + 0x5820000F, // 0053 LDCONST R8 K15 0x7C140600, // 0054 CALL R5 3 - 0xB8164000, // 0055 GETNGBL R5 K32 - 0x8C140B75, // 0056 GETMET R5 R5 K117 - 0xB81E4000, // 0057 GETNGBL R7 K32 - 0x8C1C0F76, // 0058 GETMET R7 R7 K118 + 0xB8160600, // 0055 GETNGBL R5 K3 + 0x8C140B5C, // 0056 GETMET R5 R5 K92 + 0xB81E0600, // 0057 GETNGBL R7 K3 + 0x8C1C0F5D, // 0058 GETMET R7 R7 K93 0x7C1C0200, // 0059 CALL R7 1 0x7C140400, // 005A CALL R5 2 - 0xB8164000, // 005B GETNGBL R5 K32 - 0x8C140B76, // 005C GETMET R5 R5 K118 + 0xB8160600, // 005B GETNGBL R5 K3 + 0x8C140B5D, // 005C GETMET R5 R5 K93 0x7C140200, // 005D CALL R5 1 - 0x8C140B77, // 005E GETMET R5 R5 K119 - 0x581C0000, // 005F LDCONST R7 K0 - 0x58200000, // 0060 LDCONST R8 K0 + 0x8C140B5E, // 005E GETMET R5 R5 K94 + 0x581C000F, // 005F LDCONST R7 K15 + 0x5820000F, // 0060 LDCONST R8 K15 0x7C140600, // 0061 CALL R5 3 0x60140013, // 0062 GETGBL R5 G19 0x7C140000, // 0063 CALL R5 0 - 0x90020405, // 0064 SETMBR R0 K2 R5 - 0x8C140178, // 0065 GETMET R5 R0 K120 + 0x90021605, // 0064 SETMBR R0 K11 R5 + 0x8C14015F, // 0065 GETMET R5 R0 K95 0x5C1C0400, // 0066 MOVE R7 R2 0x7C140400, // 0067 CALL R5 2 0x80000000, // 0068 RET 0 @@ -11926,70 +11653,476 @@ be_local_closure(class_HASPmota_start, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: _remove_page +********************************************************************/ +be_local_closure(class_HASPmota__remove_page, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(_remove_page), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x8808010B, // 0000 GETMBR R2 R0 K11 + 0x8C08051D, // 0001 GETMET R2 R2 K29 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x780A0003, // 0004 JMPF R2 #0009 + 0x8808010B, // 0005 GETMBR R2 R0 K11 + 0x8C08053D, // 0006 GETMET R2 R2 K61 + 0x5C100200, // 0007 MOVE R4 R1 + 0x7C080400, // 0008 CALL R2 2 + 0x80000000, // 0009 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: sort +********************************************************************/ +be_local_closure(class_HASPmota_sort, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 12, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(sort), + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x60080010, // 0001 GETGBL R2 G16 + 0x600C000C, // 0002 GETGBL R3 G12 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C0C0200, // 0004 CALL R3 1 + 0x040C0715, // 0005 SUB R3 R3 K21 + 0x400E2A03, // 0006 CONNECT R3 K21 R3 + 0x7C080200, // 0007 CALL R2 1 + 0xA8020010, // 0008 EXBLK 0 #001A + 0x5C0C0400, // 0009 MOVE R3 R2 + 0x7C0C0000, // 000A CALL R3 0 + 0x94100003, // 000B GETIDX R4 R0 R3 + 0x5C140600, // 000C MOVE R5 R3 + 0x24180B0F, // 000D GT R6 R5 K15 + 0x781A0008, // 000E JMPF R6 #0018 + 0x04180B15, // 000F SUB R6 R5 K21 + 0x94180006, // 0010 GETIDX R6 R0 R6 + 0x24180C04, // 0011 GT R6 R6 R4 + 0x781A0004, // 0012 JMPF R6 #0018 + 0x04180B15, // 0013 SUB R6 R5 K21 + 0x94180006, // 0014 GETIDX R6 R0 R6 + 0x98000A06, // 0015 SETIDX R0 R5 R6 + 0x04140B15, // 0016 SUB R5 R5 K21 + 0x7001FFF4, // 0017 JMP #000D + 0x98000A04, // 0018 SETIDX R0 R5 R4 + 0x7001FFEE, // 0019 JMP #0009 + 0x58080012, // 001A LDCONST R2 K18 + 0xAC080200, // 001B CATCH R2 1 0 + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x80040000, // 001D RET 1 R0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_obj +********************************************************************/ +be_local_closure(class_HASPmota_parse_obj, /* name */ + be_nested_proto( + 20, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(parse_obj), + &be_const_str_solidified, + ( &(const binstruction[239]) { /* code */ + 0xA40EC000, // 0000 IMPORT R3 K96 + 0xA4120200, // 0001 IMPORT R4 K1 + 0x60140009, // 0002 GETGBL R5 G9 + 0x8C180314, // 0003 GETMET R6 R1 K20 + 0x5820001F, // 0004 LDCONST R8 K31 + 0x7C180400, // 0005 CALL R6 2 + 0x7C140200, // 0006 CALL R5 1 + 0x8C180314, // 0007 GETMET R6 R1 K20 + 0x58200061, // 0008 LDCONST R8 K97 + 0x7C180400, // 0009 CALL R6 2 + 0x4C1C0000, // 000A LDNIL R7 + 0x201C0C07, // 000B NE R7 R6 R7 + 0x781E0003, // 000C JMPF R7 #0011 + 0x601C0008, // 000D GETGBL R7 G8 + 0x5C200C00, // 000E MOVE R8 R6 + 0x7C1C0200, // 000F CALL R7 1 + 0x70020000, // 0010 JMP #0012 + 0x4C1C0000, // 0011 LDNIL R7 + 0x5C180E00, // 0012 MOVE R6 R7 + 0x8C1C0120, // 0013 GETMET R7 R0 K32 + 0x7C1C0200, // 0014 CALL R7 1 + 0x4C200000, // 0015 LDNIL R8 + 0x20200A08, // 0016 NE R8 R5 R8 + 0x78220011, // 0017 JMPF R8 #002A + 0x14200B0F, // 0018 LT R8 R5 K15 + 0x74220002, // 0019 JMPT R8 #001D + 0x542200FD, // 001A LDINT R8 254 + 0x24200A08, // 001B GT R8 R5 R8 + 0x7822000C, // 001C JMPF R8 #002A + 0x20200B0F, // 001D NE R8 R5 K15 + 0x74220002, // 001E JMPT R8 #0022 + 0x4C200000, // 001F LDNIL R8 + 0x1C200C08, // 0020 EQ R8 R6 R8 + 0x78220007, // 0021 JMPF R8 #002A + 0x60200001, // 0022 GETGBL R8 G1 + 0x60240018, // 0023 GETGBL R9 G24 + 0x58280062, // 0024 LDCONST R10 K98 + 0x5C2C0A00, // 0025 MOVE R11 R5 + 0x5C300C00, // 0026 MOVE R12 R6 + 0x7C240600, // 0027 CALL R9 3 + 0x7C200200, // 0028 CALL R8 1 + 0x80001000, // 0029 RET 0 + 0x8C200F63, // 002A GETMET R8 R7 K99 + 0x5C280A00, // 002B MOVE R10 R5 + 0x7C200400, // 002C CALL R8 2 + 0x4C240000, // 002D LDNIL R9 + 0x20240C09, // 002E NE R9 R6 R9 + 0x7826005F, // 002F JMPF R9 #0090 + 0x4C240000, // 0030 LDNIL R9 + 0x20240A09, // 0031 NE R9 R5 R9 + 0x7826005C, // 0032 JMPF R9 #0090 + 0x4C240000, // 0033 LDNIL R9 + 0x1C241009, // 0034 EQ R9 R8 R9 + 0x78260059, // 0035 JMPF R9 #0090 + 0x60240009, // 0036 GETGBL R9 G9 + 0x8C280314, // 0037 GETMET R10 R1 K20 + 0x58300064, // 0038 LDCONST R12 K100 + 0x7C280400, // 0039 CALL R10 2 + 0x7C240200, // 003A CALL R9 1 + 0x4C280000, // 003B LDNIL R10 + 0x4C2C0000, // 003C LDNIL R11 + 0x4C300000, // 003D LDNIL R12 + 0x2030120C, // 003E NE R12 R9 R12 + 0x78320007, // 003F JMPF R12 #0048 + 0x8C300F63, // 0040 GETMET R12 R7 K99 + 0x5C381200, // 0041 MOVE R14 R9 + 0x7C300400, // 0042 CALL R12 2 + 0x5C281800, // 0043 MOVE R10 R12 + 0x4C300000, // 0044 LDNIL R12 + 0x2030140C, // 0045 NE R12 R10 R12 + 0x78320000, // 0046 JMPF R12 #0048 + 0x882C152A, // 0047 GETMBR R11 R10 K42 + 0x4C300000, // 0048 LDNIL R12 + 0x1C30160C, // 0049 EQ R12 R11 R12 + 0x78320002, // 004A JMPF R12 #004E + 0x8C300F65, // 004B GETMET R12 R7 K101 + 0x7C300200, // 004C CALL R12 1 + 0x5C2C1800, // 004D MOVE R11 R12 + 0x8C300902, // 004E GETMET R12 R4 K2 + 0x5C380000, // 004F MOVE R14 R0 + 0x003ECC06, // 0050 ADD R15 K102 R6 + 0x7C300600, // 0051 CALL R12 3 + 0x4C340000, // 0052 LDNIL R13 + 0x4C380000, // 0053 LDNIL R14 + 0x1C38180E, // 0054 EQ R14 R12 R14 + 0x783A0010, // 0055 JMPF R14 #0067 + 0x8C380902, // 0056 GETMET R14 R4 K2 + 0x5C400600, // 0057 MOVE R16 R3 + 0x5C440C00, // 0058 MOVE R17 R6 + 0x7C380600, // 0059 CALL R14 3 + 0x4C3C0000, // 005A LDNIL R15 + 0x203C1C0F, // 005B NE R15 R14 R15 + 0x783E0009, // 005C JMPF R15 #0067 + 0x603C0004, // 005D GETGBL R15 G4 + 0x5C401C00, // 005E MOVE R16 R14 + 0x7C3C0200, // 005F CALL R15 1 + 0x1C3C1F67, // 0060 EQ R15 R15 K103 + 0x783E0004, // 0061 JMPF R15 #0067 + 0x5C3C1C00, // 0062 MOVE R15 R14 + 0x5C401600, // 0063 MOVE R16 R11 + 0x7C3C0200, // 0064 CALL R15 1 + 0x5C341E00, // 0065 MOVE R13 R15 + 0x88300168, // 0066 GETMBR R12 R0 K104 + 0x4C380000, // 0067 LDNIL R14 + 0x1C38180E, // 0068 EQ R14 R12 R14 + 0x783A000F, // 0069 JMPF R14 #007A + 0x8C380969, // 006A GETMET R14 R4 K105 + 0x5C400C00, // 006B MOVE R16 R6 + 0x7C380400, // 006C CALL R14 2 + 0x4C3C0000, // 006D LDNIL R15 + 0x203C1C0F, // 006E NE R15 R14 R15 + 0x783E0009, // 006F JMPF R15 #007A + 0x603C0004, // 0070 GETGBL R15 G4 + 0x5C401C00, // 0071 MOVE R16 R14 + 0x7C3C0200, // 0072 CALL R15 1 + 0x1C3C1F67, // 0073 EQ R15 R15 K103 + 0x783E0004, // 0074 JMPF R15 #007A + 0x5C3C1C00, // 0075 MOVE R15 R14 + 0x5C401600, // 0076 MOVE R16 R11 + 0x7C3C0200, // 0077 CALL R15 1 + 0x5C341E00, // 0078 MOVE R13 R15 + 0x88300168, // 0079 GETMBR R12 R0 K104 + 0x4C380000, // 007A LDNIL R14 + 0x1C38180E, // 007B EQ R14 R12 R14 + 0x783A0006, // 007C JMPF R14 #0084 + 0x60380001, // 007D GETGBL R14 G1 + 0x603C0018, // 007E GETGBL R15 G24 + 0x5840006A, // 007F LDCONST R16 K106 + 0x5C440C00, // 0080 MOVE R17 R6 + 0x7C3C0400, // 0081 CALL R15 2 + 0x7C380200, // 0082 CALL R14 1 + 0x80001C00, // 0083 RET 0 + 0x5C381800, // 0084 MOVE R14 R12 + 0x5C3C1600, // 0085 MOVE R15 R11 + 0x5C400400, // 0086 MOVE R16 R2 + 0x5C440200, // 0087 MOVE R17 R1 + 0x5C481A00, // 0088 MOVE R18 R13 + 0x5C4C1400, // 0089 MOVE R19 R10 + 0x7C380A00, // 008A CALL R14 5 + 0x5C201C00, // 008B MOVE R8 R14 + 0x8C380F6B, // 008C GETMET R14 R7 K107 + 0x5C400A00, // 008D MOVE R16 R5 + 0x5C441000, // 008E MOVE R17 R8 + 0x7C380600, // 008F CALL R14 3 + 0x1C240B0F, // 0090 EQ R9 R5 K15 + 0x7826000F, // 0091 JMPF R9 #00A2 + 0x4C240000, // 0092 LDNIL R9 + 0x20240C09, // 0093 NE R9 R6 R9 + 0x78260006, // 0094 JMPF R9 #009C + 0x60240001, // 0095 GETGBL R9 G1 + 0x60280018, // 0096 GETGBL R10 G24 + 0x582C006C, // 0097 LDCONST R11 K108 + 0x5C300C00, // 0098 MOVE R12 R6 + 0x7C280400, // 0099 CALL R10 2 + 0x7C240200, // 009A CALL R9 1 + 0x80001200, // 009B RET 0 + 0x8C240120, // 009C GETMET R9 R0 K32 + 0x7C240200, // 009D CALL R9 1 + 0x8C241363, // 009E GETMET R9 R9 K99 + 0x582C000F, // 009F LDCONST R11 K15 + 0x7C240400, // 00A0 CALL R9 2 + 0x5C201200, // 00A1 MOVE R8 R9 + 0x4C240000, // 00A2 LDNIL R9 + 0x20241009, // 00A3 NE R9 R8 R9 + 0x7826000C, // 00A4 JMPF R9 #00B2 + 0x60240010, // 00A5 GETGBL R9 G16 + 0x8C280310, // 00A6 GETMET R10 R1 K16 + 0x7C280200, // 00A7 CALL R10 1 + 0x7C240200, // 00A8 CALL R9 1 + 0xA8020004, // 00A9 EXBLK 0 #00AF + 0x5C281200, // 00AA MOVE R10 R9 + 0x7C280000, // 00AB CALL R10 0 + 0x942C020A, // 00AC GETIDX R11 R1 R10 + 0x9020140B, // 00AD SETMBR R8 R10 R11 + 0x7001FFFA, // 00AE JMP #00AA + 0x58240012, // 00AF LDCONST R9 K18 + 0xAC240200, // 00B0 CATCH R9 1 0 + 0xB0080000, // 00B1 RAISE 2 R0 R0 + 0x4C240000, // 00B2 LDNIL R9 + 0x20241009, // 00B3 NE R9 R8 R9 + 0x78260001, // 00B4 JMPF R9 #00B7 + 0x8C24116D, // 00B5 GETMET R9 R8 K109 + 0x7C240200, // 00B6 CALL R9 1 + 0x4C240000, // 00B7 LDNIL R9 + 0x60280008, // 00B8 GETGBL R10 G8 + 0x8C2C0314, // 00B9 GETMET R11 R1 K20 + 0x5834006E, // 00BA LDCONST R13 K110 + 0x7C2C0400, // 00BB CALL R11 2 + 0x7C280200, // 00BC CALL R10 1 + 0x202C156F, // 00BD NE R11 R10 K111 + 0x782E0012, // 00BE JMPF R11 #00D2 + 0xA8020005, // 00BF EXBLK 0 #00C6 + 0x602C000D, // 00C0 GETGBL R11 G13 + 0x5C301400, // 00C1 MOVE R12 R10 + 0x7C2C0200, // 00C2 CALL R11 1 + 0x5C241600, // 00C3 MOVE R9 R11 + 0xA8040001, // 00C4 EXBLK 1 1 + 0x7002000B, // 00C5 JMP #00D2 + 0xAC2C0002, // 00C6 CATCH R11 0 2 + 0x70020008, // 00C7 JMP #00D1 + 0x60340001, // 00C8 GETGBL R13 G1 + 0x60380018, // 00C9 GETGBL R14 G24 + 0x583C0070, // 00CA LDCONST R15 K112 + 0x5C401400, // 00CB MOVE R16 R10 + 0x5C441600, // 00CC MOVE R17 R11 + 0x5C481800, // 00CD MOVE R18 R12 + 0x7C380800, // 00CE CALL R14 4 + 0x7C340200, // 00CF CALL R13 1 + 0x70020000, // 00D0 JMP #00D2 + 0xB0080000, // 00D1 RAISE 2 R0 R0 + 0x4C2C0000, // 00D2 LDNIL R11 + 0x202C120B, // 00D3 NE R11 R9 R11 + 0x782E0018, // 00D4 JMPF R11 #00EE + 0xA802000B, // 00D5 EXBLK 0 #00E2 + 0x5C2C1200, // 00D6 MOVE R11 R9 + 0x7C2C0000, // 00D7 CALL R11 0 + 0x60300004, // 00D8 GETGBL R12 G4 + 0x5C341600, // 00D9 MOVE R13 R11 + 0x7C300200, // 00DA CALL R12 1 + 0x1C301971, // 00DB EQ R12 R12 K113 + 0x78320002, // 00DC JMPF R12 #00E0 + 0x5C301600, // 00DD MOVE R12 R11 + 0x5C341000, // 00DE MOVE R13 R8 + 0x7C300200, // 00DF CALL R12 1 + 0xA8040001, // 00E0 EXBLK 1 1 + 0x7002000B, // 00E1 JMP #00EE + 0xAC2C0002, // 00E2 CATCH R11 0 2 + 0x70020008, // 00E3 JMP #00ED + 0x60340001, // 00E4 GETGBL R13 G1 + 0x60380018, // 00E5 GETGBL R14 G24 + 0x583C0072, // 00E6 LDCONST R15 K114 + 0x5C401400, // 00E7 MOVE R16 R10 + 0x5C441600, // 00E8 MOVE R17 R11 + 0x5C481800, // 00E9 MOVE R18 R12 + 0x7C380800, // 00EA CALL R14 4 + 0x7C340200, // 00EB CALL R13 1 + 0x70020000, // 00EC JMP #00EE + 0xB0080000, // 00ED RAISE 2 R0 R0 + 0x80000000, // 00EE RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_dispatch +********************************************************************/ +be_local_closure(class_HASPmota_event_dispatch, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(event_dispatch), + &be_const_str_solidified, + ( &(const binstruction[34]) { /* code */ + 0xA40A0200, // 0000 IMPORT R2 K1 + 0x8C0C052C, // 0001 GETMET R3 R2 K44 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x88100173, // 0004 GETMBR R4 R0 K115 + 0x78120002, // 0005 JMPF R4 #0009 + 0x88100173, // 0006 GETMBR R4 R0 K115 + 0x9012E803, // 0007 SETMBR R4 K116 R3 + 0x70020004, // 0008 JMP #000E + 0xB8120600, // 0009 GETNGBL R4 K3 + 0x8C100975, // 000A GETMET R4 R4 K117 + 0x5C180600, // 000B MOVE R6 R3 + 0x7C100400, // 000C CALL R4 2 + 0x9002E604, // 000D SETMBR R0 K115 R4 + 0x88100173, // 000E GETMBR R4 R0 K115 + 0x8C100976, // 000F GETMET R4 R4 K118 + 0x7C100200, // 0010 CALL R4 1 + 0x60140009, // 0011 GETGBL R5 G9 + 0x5C180800, // 0012 MOVE R6 R4 + 0x7C140200, // 0013 CALL R5 1 + 0x20140B0F, // 0014 NE R5 R5 K15 + 0x7816000A, // 0015 JMPF R5 #0021 + 0x8C140577, // 0016 GETMET R5 R2 K119 + 0x5C1C0800, // 0017 MOVE R7 R4 + 0x7C140400, // 0018 CALL R5 2 + 0x60180004, // 0019 GETGBL R6 G4 + 0x5C1C0A00, // 001A MOVE R7 R5 + 0x7C180200, // 001B CALL R6 1 + 0x1C180D08, // 001C EQ R6 R6 K8 + 0x781A0002, // 001D JMPF R6 #0021 + 0x8C180B28, // 001E GETMET R6 R5 K40 + 0x88200173, // 001F GETMBR R8 R0 K115 + 0x7C180400, // 0020 CALL R6 2 + 0x80000000, // 0021 RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified class: HASPmota ********************************************************************/ be_local_class(HASPmota, 10, NULL, - be_nested_map(56, + be_nested_map(57, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(pages_list_sorted, -1), be_const_closure(class_HASPmota_pages_list_sorted_closure) }, - { be_const_key_weak(lvh_spangroup, -1), be_const_class(be_class_lvh_spangroup) }, - { be_const_key_weak(lvh_roller, -1), be_const_class(be_class_lvh_roller) }, - { be_const_key_weak(lvh_slider, -1), be_const_class(be_class_lvh_slider) }, - { be_const_key_weak(lvh_line, 14), be_const_class(be_class_lvh_line) }, - { be_const_key_weak(start, -1), be_const_closure(class_HASPmota_start_closure) }, - { be_const_key_weak(get_page_cur, -1), be_const_closure(class_HASPmota_get_page_cur_closure) }, - { be_const_key_weak(lvh_btnmatrix, 43), be_const_class(be_class_lvh_btnmatrix) }, - { be_const_key_weak(dark, -1), be_const_var(0) }, - { be_const_key_weak(lvh_checkbox, -1), be_const_class(be_class_lvh_checkbox) }, - { be_const_key_weak(lvh_chart, -1), be_const_class(be_class_lvh_chart) }, - { be_const_key_weak(lvh_scale_line, 9), be_const_class(be_class_lvh_scale_line) }, - { be_const_key_weak(parse, -1), be_const_closure(class_HASPmota_parse_closure) }, - { be_const_key_weak(lvh_page, 20), be_const_class(be_class_lvh_page) }, - { be_const_key_weak(lvh_msgbox, -1), be_const_class(be_class_lvh_msgbox) }, - { be_const_key_weak(lvh_spinner, -1), be_const_class(be_class_lvh_spinner) }, - { be_const_key_weak(lvh_obj, 23), be_const_class(be_class_lvh_obj) }, - { be_const_key_weak(sort, -1), be_const_static_closure(class_HASPmota_sort_closure) }, - { be_const_key_weak(event_dispatch, 27), be_const_closure(class_HASPmota_event_dispatch_closure) }, - { be_const_key_weak(scr, 16), be_const_var(3) }, - { be_const_key_weak(lvh_img, -1), be_const_class(be_class_lvh_img) }, - { be_const_key_weak(vres, -1), be_const_var(2) }, - { be_const_key_weak(lvh_span, 26), be_const_class(be_class_lvh_span) }, - { be_const_key_weak(init, -1), be_const_closure(class_HASPmota_init_closure) }, - { be_const_key_weak(lvh_fixed, -1), be_const_class(be_class_lvh_fixed) }, - { be_const_key_weak(event_cb, -1), be_const_var(9) }, - { be_const_key_weak(_load, -1), be_const_closure(class_HASPmota__load_closure) }, - { be_const_key_weak(lvh_root, 50), be_const_class(be_class_lvh_root) }, - { be_const_key_weak(fix_lv_version, -1), be_const_static_closure(class_HASPmota_fix_lv_version_closure) }, - { be_const_key_weak(def_templ_name, -1), be_nested_str_weak(pages_X2Ejsonl) }, - { be_const_key_weak(parse_obj, 40), be_const_closure(class_HASPmota_parse_obj_closure) }, - { be_const_key_weak(hres, -1), be_const_var(1) }, - { be_const_key_weak(lvh_scale_section, -1), be_const_class(be_class_lvh_scale_section) }, - { be_const_key_weak(lvh_scale, 36), be_const_class(be_class_lvh_scale) }, - { be_const_key_weak(lvh_pages, 41), be_const_var(5) }, - { be_const_key_weak(do_action, -1), be_const_closure(class_HASPmota_do_action_closure) }, - { be_const_key_weak(lvh_label, -1), be_const_class(be_class_lvh_label) }, - { be_const_key_weak(lvh_scr, -1), be_const_class(be_class_lvh_scr) }, - { be_const_key_weak(lvh_switch, -1), be_const_class(be_class_lvh_switch) }, - { be_const_key_weak(event, -1), be_const_var(8) }, - { be_const_key_weak(re_page_target, -1), be_const_var(7) }, - { be_const_key_weak(parse_page, 45), be_const_closure(class_HASPmota_parse_page_closure) }, - { be_const_key_weak(lvh_arc, 37), be_const_class(be_class_lvh_arc) }, - { be_const_key_weak(lvh_led, 51), be_const_class(be_class_lvh_led) }, - { be_const_key_weak(lvh_page_cur_idx, 33), be_const_var(6) }, - { be_const_key_weak(page_dir_to, -1), be_const_closure(class_HASPmota_page_dir_to_closure) }, - { be_const_key_weak(r16, -1), be_const_var(4) }, - { be_const_key_weak(lvh_bar, -1), be_const_class(be_class_lvh_bar) }, + { be_const_key_weak(re_page_target, 4), be_const_var(7) }, + { be_const_key_weak(lvh_line, -1), be_const_class(be_class_lvh_line) }, + { be_const_key_weak(lvh_pages, -1), be_const_var(5) }, { be_const_key_weak(lvh_dropdown_list, -1), be_const_class(be_class_lvh_dropdown_list) }, - { be_const_key_weak(lvh_flex, 17), be_const_class(be_class_lvh_flex) }, + { be_const_key_weak(lvh_dropdown, -1), be_const_class(be_class_lvh_dropdown) }, + { be_const_key_weak(lvh_label, 53), be_const_class(be_class_lvh_label) }, + { be_const_key_weak(lvh_spinner, -1), be_const_class(be_class_lvh_spinner) }, + { be_const_key_weak(lvh_scale, -1), be_const_class(be_class_lvh_scale) }, + { be_const_key_weak(lvh_obj, -1), be_const_class(be_class_lvh_obj) }, + { be_const_key_weak(event_dispatch, -1), be_const_closure(class_HASPmota_event_dispatch_closure) }, + { be_const_key_weak(parse, 2), be_const_closure(class_HASPmota_parse_closure) }, + { be_const_key_weak(scr, -1), be_const_var(3) }, + { be_const_key_weak(lvh_msgbox, 25), be_const_class(be_class_lvh_msgbox) }, + { be_const_key_weak(lvh_fixed, -1), be_const_class(be_class_lvh_fixed) }, + { be_const_key_weak(lvh_checkbox, -1), be_const_class(be_class_lvh_checkbox) }, + { be_const_key_weak(hres, 49), be_const_var(1) }, + { be_const_key_weak(lvh_page, 46), be_const_class(be_class_lvh_page) }, + { be_const_key_weak(sort, -1), be_const_static_closure(class_HASPmota_sort_closure) }, + { be_const_key_weak(dark, 32), be_const_var(0) }, + { be_const_key_weak(lvh_scale_line, -1), be_const_class(be_class_lvh_scale_line) }, + { be_const_key_weak(get_page_cur, -1), be_const_closure(class_HASPmota_get_page_cur_closure) }, + { be_const_key_weak(event, -1), be_const_var(8) }, + { be_const_key_weak(lvh_led, -1), be_const_class(be_class_lvh_led) }, + { be_const_key_weak(parse_page, -1), be_const_closure(class_HASPmota_parse_page_closure) }, + { be_const_key_weak(r16, -1), be_const_var(4) }, + { be_const_key_weak(event_cb, 13), be_const_var(9) }, { be_const_key_weak(lvh_btn, -1), be_const_class(be_class_lvh_btn) }, + { be_const_key_weak(lvh_bar, -1), be_const_class(be_class_lvh_bar) }, + { be_const_key_weak(lvh_scale_section, 38), be_const_class(be_class_lvh_scale_section) }, + { be_const_key_weak(do_action, -1), be_const_closure(class_HASPmota_do_action_closure) }, + { be_const_key_weak(lvh_root, -1), be_const_class(be_class_lvh_root) }, + { be_const_key_weak(_remove_page, 43), be_const_closure(class_HASPmota__remove_page_closure) }, + { be_const_key_weak(lvh_roller, -1), be_const_class(be_class_lvh_roller) }, + { be_const_key_weak(lvh_img, 16), be_const_class(be_class_lvh_img) }, + { be_const_key_weak(lvh_qrcode, 35), be_const_class(be_class_lvh_qrcode) }, + { be_const_key_weak(lvh_span, -1), be_const_class(be_class_lvh_span) }, + { be_const_key_weak(page_dir_to, -1), be_const_closure(class_HASPmota_page_dir_to_closure) }, + { be_const_key_weak(def_templ_name, -1), be_nested_str_weak(pages_X2Ejsonl) }, + { be_const_key_weak(lvh_switch, -1), be_const_class(be_class_lvh_switch) }, + { be_const_key_weak(lvh_slider, -1), be_const_class(be_class_lvh_slider) }, + { be_const_key_weak(page_show, -1), be_const_closure(class_HASPmota_page_show_closure) }, + { be_const_key_weak(start, -1), be_const_closure(class_HASPmota_start_closure) }, + { be_const_key_weak(pages_list_sorted, 34), be_const_closure(class_HASPmota_pages_list_sorted_closure) }, + { be_const_key_weak(_load, -1), be_const_closure(class_HASPmota__load_closure) }, + { be_const_key_weak(lvh_scr, -1), be_const_class(be_class_lvh_scr) }, + { be_const_key_weak(lvh_chart, 31), be_const_class(be_class_lvh_chart) }, { be_const_key_weak(register_event, -1), be_const_closure(class_HASPmota_register_event_closure) }, - { be_const_key_weak(lvh_qrcode, -1), be_const_class(be_class_lvh_qrcode) }, - { be_const_key_weak(lvh_cpicker, 8), be_const_class(be_class_lvh_cpicker) }, - { be_const_key_weak(page_show, 6), be_const_closure(class_HASPmota_page_show_closure) }, - { be_const_key_weak(lvh_dropdown, 5), be_const_class(be_class_lvh_dropdown) }, + { be_const_key_weak(lvh_btnmatrix, 18), be_const_class(be_class_lvh_btnmatrix) }, + { be_const_key_weak(lvh_cpicker, 17), be_const_class(be_class_lvh_cpicker) }, + { be_const_key_weak(lvh_flex, -1), be_const_class(be_class_lvh_flex) }, + { be_const_key_weak(parse_obj, 8), be_const_closure(class_HASPmota_parse_obj_closure) }, + { be_const_key_weak(init, 12), be_const_closure(class_HASPmota_init_closure) }, + { be_const_key_weak(vres, 9), be_const_var(2) }, + { be_const_key_weak(lvh_page_cur_idx, -1), be_const_var(6) }, + { be_const_key_weak(fix_lv_version, 7), be_const_static_closure(class_HASPmota_fix_lv_version_closure) }, + { be_const_key_weak(lvh_arc, -1), be_const_class(be_class_lvh_arc) }, + { be_const_key_weak(lvh_spangroup, -1), be_const_class(be_class_lvh_spangroup) }, })), be_str_weak(HASPmota) ); From 92a56a80b44bedca40729c5cbff687938ab003dc Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 17 Oct 2024 22:14:21 +0200 Subject: [PATCH 013/205] try to fix if condition --- lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h index 79377c47e..c9fc61bb2 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h +++ b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMIDI.h @@ -21,7 +21,7 @@ #ifndef _AUDIOGENERATORMIDI_H #define _AUDIOGENERATORMIDI_H -#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__) +#if defined(ESP32) // Do not build, Espressif's GCC8+ has a compiler bug #else // __GNUC__ == 8 From 66213c88c11430ff12127018623e3f840a17922b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:23:10 +0200 Subject: [PATCH 014/205] dedicated special framework "ITEAD" not needed anymore (#22303) --- platformio_tasmota_env32.ini | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index ef8d46a58..add832673 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -262,7 +262,6 @@ board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv build_flags = ${env:tasmota32_base.build_flags} -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-zbbrdgpro.bin"' -DFIRMWARE_ZBBRDGPRO - -DFRAMEWORK_ARDUINO_ITEAD custom_files_upload = ${env:tasmota32_base.custom_files_upload} tools/fw_SonoffZigbeeBridgePro_cc2652/Sonoff_ZBPro.autoconf tasmota/berry/zigbee/cc2652_flasher.be @@ -270,13 +269,16 @@ custom_files_upload = ${env:tasmota32_base.custom_files_upload} tasmota/berry/zigbee/sonoff_zb_pro_flasher.be tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20220219.hex lib_extra_dirs = lib/lib_basic, lib/lib_ssl, lib/libesp32 +custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 + CONFIG_D0WD_PSRAM_CS_IO=18 [env:tasmota32-nspanel] extends = env:tasmota32_base build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_NSPANEL - -DFRAMEWORK_ARDUINO_ITEAD -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin"' +custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 + CONFIG_D0WD_PSRAM_CS_IO=18 [env:tasmota32-AD] extends = env:tasmota32_base From 813dc27360ac00d52fbca918ebff1c6894b4b7ca Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:34:36 +0200 Subject: [PATCH 015/205] Revert "dedicated special framework "ITEAD" not needed anymore (#22303)" (#22314) This reverts commit 66213c88c11430ff12127018623e3f840a17922b. --- platformio_tasmota_env32.ini | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index add832673..ef8d46a58 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -262,6 +262,7 @@ board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv build_flags = ${env:tasmota32_base.build_flags} -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-zbbrdgpro.bin"' -DFIRMWARE_ZBBRDGPRO + -DFRAMEWORK_ARDUINO_ITEAD custom_files_upload = ${env:tasmota32_base.custom_files_upload} tools/fw_SonoffZigbeeBridgePro_cc2652/Sonoff_ZBPro.autoconf tasmota/berry/zigbee/cc2652_flasher.be @@ -269,16 +270,13 @@ custom_files_upload = ${env:tasmota32_base.custom_files_upload} tasmota/berry/zigbee/sonoff_zb_pro_flasher.be tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20220219.hex lib_extra_dirs = lib/lib_basic, lib/lib_ssl, lib/libesp32 -custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 - CONFIG_D0WD_PSRAM_CS_IO=18 [env:tasmota32-nspanel] extends = env:tasmota32_base build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_NSPANEL + -DFRAMEWORK_ARDUINO_ITEAD -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin"' -custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 - CONFIG_D0WD_PSRAM_CS_IO=18 [env:tasmota32-AD] extends = env:tasmota32_base From f320ca2982c472362bb5a6fe1f51d797e18e5c04 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:18:10 +0200 Subject: [PATCH 016/205] Phase out of Tasmota espressif32 frameworks `solo1` and `ITEAD` (#22315) * Step 1 of phase out of special frameworks solo1 and ITEAD --- .github/workflows/build_all_the_things.yml | 4 +-- boards/{esp32_solo1.json => esp32-solo1.json} | 0 pio-tools/post_esp32.py | 32 +++---------------- pio-tools/strip-flags.py | 4 +-- platformio_override_sample.ini | 2 -- platformio_tasmota_cenv_sample.ini | 3 +- platformio_tasmota_env32.ini | 16 ++++++---- 7 files changed, 21 insertions(+), 40 deletions(-) rename boards/{esp32_solo1.json => esp32-solo1.json} (100%) diff --git a/.github/workflows/build_all_the_things.yml b/.github/workflows/build_all_the_things.yml index 365b1ca81..aa80aa913 100644 --- a/.github/workflows/build_all_the_things.yml +++ b/.github/workflows/build_all_the_things.yml @@ -25,7 +25,7 @@ jobs: fail-fast: true matrix: variant: - - tasmota32solo1-safeboot + - tasmota32-webcam steps: - uses: actions/checkout@v4 - name: Set up Python @@ -53,7 +53,7 @@ jobs: fail-fast: true matrix: variant: - - tasmota32-webcam + - tasmota32solo1-safeboot steps: - uses: actions/checkout@v4 - name: Set up Python diff --git a/boards/esp32_solo1.json b/boards/esp32-solo1.json similarity index 100% rename from boards/esp32_solo1.json rename to boards/esp32-solo1.json diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py index e296be29e..f0af4322a 100644 --- a/pio-tools/post_esp32.py +++ b/pio-tools/post_esp32.py @@ -43,30 +43,14 @@ variant = env.BoardConfig().get("build.variant", "") sections = env.subst(env.get("FLASH_EXTRA_IMAGES")) chip = env.get("BOARD_MCU") mcu_build_variant = env.BoardConfig().get("build.variant", "").lower() +FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") # Copy safeboots firmwares in place when running in Github github_actions = os.getenv('GITHUB_ACTIONS') -extra_flags = ''.join([element.replace("-D", " ") for element in env.BoardConfig().get("build.extra_flags", "")]) -build_flags = ''.join([element.replace("-D", " ") for element in env.GetProjectOption("build_flags")]) - -if "CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags: - FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-solo1") - if github_actions and os.path.exists("./firmware/firmware"): - shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-solo1/variants/tasmota") - if variants_dir: - shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) -elif "CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags: - FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-ITEAD") - if github_actions and os.path.exists("./firmware/firmware"): - shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-ITEAD/variants/tasmota") - if variants_dir: - shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) -else: - FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") - if github_actions and os.path.exists("./firmware/firmware"): - shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduinoespressif32/variants/tasmota") - if variants_dir: - shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) +if github_actions and os.path.exists("./firmware/firmware"): + shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduinoespressif32/variants/tasmota", dirs_exist_ok=True) + if variants_dir: + shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) # Copy pins_arduino.h to variants folder if variants_dir: @@ -129,12 +113,6 @@ def patch_partitions_bin(size_string): def esp32_create_chip_string(chip): tasmota_platform_org = env.subst("$BUILD_DIR").split(os.path.sep)[-1] tasmota_platform = tasmota_platform_org.split('-')[0] - if ("CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags) and "tasmota32-safeboot" not in tasmota_platform_org and "tasmota32solo1" not in tasmota_platform_org: - print(Fore.YELLOW + "Unexpected naming convention in this build environment:" + Fore.RED, tasmota_platform_org) - print(Fore.YELLOW + "Expected build environment name like " + Fore.GREEN + "'tasmota32solo1-whatever-you-want'") - print(Fore.YELLOW + "Please correct your actual build environment, to avoid undefined behavior in build process!!") - tasmota_platform = "tasmota32solo1" - return tasmota_platform if "tasmota" + chip[3:] not in tasmota_platform: # check + fix for a valid name like 'tasmota' + '32c3' tasmota_platform = "tasmota" + chip[3:] if "-DUSE_USB_CDC_CONSOLE" not in env.BoardConfig().get("build.extra_flags"): diff --git a/pio-tools/strip-flags.py b/pio-tools/strip-flags.py index 981918273..60cabbde3 100644 --- a/pio-tools/strip-flags.py +++ b/pio-tools/strip-flags.py @@ -8,8 +8,8 @@ if "FIRMWARE_SAFEBOOT" in build_flags: try: link_flags.pop(link_flags.index("-Wl,--wrap=panicHandler")) except: - do_nothing="" + pass try: link_flags.pop(link_flags.index("-Wl,--wrap=xt_unhandled_exception")) except: - do_nothing="" \ No newline at end of file + pass diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 7604a1144..22ea0d674 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -80,8 +80,6 @@ lib_extra_dirs = ${library.lib_extra_dirs} ;platform = https://github.com/Jason2866/platform-espressif32/releases/download/2024.07.22/platform-espressif32.zip ;platform_packages = framework-arduinoespressif32 @ -; framework-arduino-solo1 @ -; framework-arduino-ITEAD @ ;build_unflags = ${esp32_defaults.build_unflags} ;build_flags = ${esp32_defaults.build_flags} ;board = esp32 diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini index 8ba11666b..9c0576147 100644 --- a/platformio_tasmota_cenv_sample.ini +++ b/platformio_tasmota_cenv_sample.ini @@ -177,13 +177,14 @@ build_flags = ${env:tasmota32_base.build_flags} [env:tasmota32solo1-ocd] build_type = debug extends = env:tasmota32solo1 -board = esp32_solo1 +board = esp32-solo1 debug_tool = esp-prog upload_protocol = esp-prog debug_init_break = tbreak setup build_unflags = ${env:tasmota32_base.build_unflags} build_flags = ${env:tasmota32_base.build_flags} -DOTA_URL='""' +custom_sdkconfig = CONFIG_FREERTOS_UNICORE=y [env:tasmota32s2-ocd] build_type = debug diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index ef8d46a58..16f51e842 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -28,24 +28,25 @@ custom_files_upload = no_files [env:tasmota32-safeboot] extends = env:tasmota32_base -board = esp32_solo1 +board = esp32-solo1 board_build.app_partition_name = safeboot build_flags = ${env:tasmota32_base.build_flags} - -DFRAMEWORK_ARDUINO_SOLO1 -DFIRMWARE_SAFEBOOT -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-safeboot.bin"' lib_extra_dirs = lib/lib_ssl, lib/libesp32 lib_ignore = ${safeboot_flags.lib_ignore} +custom_sdkconfig = CONFIG_FREERTOS_UNICORE=y [env:tasmota32solo1-safeboot] extends = env:tasmota32_base -board = esp32_solo1 +board = esp32-solo1 board_build.app_partition_name = safeboot build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32solo1-safeboot.bin"' lib_extra_dirs = lib/lib_ssl, lib/libesp32 lib_ignore = ${safeboot_flags.lib_ignore} +custom_sdkconfig = CONFIG_FREERTOS_UNICORE=y [env:tasmota32s2-safeboot] extends = env:tasmota32_base @@ -145,7 +146,7 @@ build_flags = ${env:tasmota32_base.build_flags} [env:tasmota32solo1] extends = env:tasmota32_base -board = esp32_solo1 +board = esp32-solo1 build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32 -DCODE_IMAGE_STR='"solo1"' @@ -153,6 +154,7 @@ build_flags = ${env:tasmota32_base.build_flags} lib_ignore = ${env:tasmota32_base.lib_ignore} Micro-RTSP epdiy +custom_sdkconfig = CONFIG_FREERTOS_UNICORE=y [env:tasmota32s2] extends = env:tasmota32_base @@ -262,7 +264,6 @@ board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv build_flags = ${env:tasmota32_base.build_flags} -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-zbbrdgpro.bin"' -DFIRMWARE_ZBBRDGPRO - -DFRAMEWORK_ARDUINO_ITEAD custom_files_upload = ${env:tasmota32_base.custom_files_upload} tools/fw_SonoffZigbeeBridgePro_cc2652/Sonoff_ZBPro.autoconf tasmota/berry/zigbee/cc2652_flasher.be @@ -270,13 +271,16 @@ custom_files_upload = ${env:tasmota32_base.custom_files_upload} tasmota/berry/zigbee/sonoff_zb_pro_flasher.be tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20220219.hex lib_extra_dirs = lib/lib_basic, lib/lib_ssl, lib/libesp32 +custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 + CONFIG_D0WD_PSRAM_CS_IO=18 [env:tasmota32-nspanel] extends = env:tasmota32_base build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_NSPANEL - -DFRAMEWORK_ARDUINO_ITEAD -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin"' +custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 + CONFIG_D0WD_PSRAM_CS_IO=18 [env:tasmota32-AD] extends = env:tasmota32_base From 91604b9f2a9a11ce1a44c8974488338ce4854b93 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 18 Oct 2024 23:06:26 +0200 Subject: [PATCH 017/205] Update changelogs --- CHANGELOG.md | 2 +- RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49ca989e1..66fe25df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file. ### Changed - ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 (#22299) -- HASPmota support for page delet and object updates +- HASPmota support for page delete and object updates (#22311) ### Fixed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 61b6aab1a..741bbc3d1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -123,6 +123,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Changed - ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 [#22299](https://github.com/arendst/Tasmota/issues/22299) +- HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed From 04c0aa13eace88c0c2fcb00e9fb22b2c88c671d6 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Fri, 18 Oct 2024 23:42:52 +0200 Subject: [PATCH 018/205] HASPmota support for page delete and object updates (improved) (#22319) --- .../lv_haspmota/src/embedded/lv_haspmota.be | 136 +- .../src/solidify/solidified_lv_haspmota.h | 1974 ++++++++++------- tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino | 2 +- 3 files changed, 1231 insertions(+), 881 deletions(-) diff --git a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be index 1332a3ec8..93b6acbd2 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be +++ b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be @@ -136,7 +136,8 @@ class lvh_root return def () end end def _delete() - # to be overriden + # remove from page + self._page.remove_obj(self.id) end ################################################################################# @@ -668,8 +669,7 @@ class lvh_obj : lvh_root self.remove_text_rule() if (self._lv_label) self._lv_label.del() self._lv_label = nil end if (self._lv_obj) self._lv_obj.del() self._lv_obj = nil end - # remove from page - self._page.remove_obj(self.id) + super(self)._delete() end #==================================================================== @@ -1869,6 +1869,7 @@ class lvh_scale_section : lvh_root self._style10 = nil self._style30.del() self._style30 = nil + super(self)._delete() end #- ------------------------------------------------------------# @@ -2365,14 +2366,43 @@ class lvh_page # create a global for this page of form p, ex `p1` # create a global for the page attributes as pb0, ex `p1b0` - global.("p" + str(self._page_id)) = self - global.("p" + str(self._page_id) + "b0") = obj_scr + global.(f"p{self._page_id}") = self + global.(f"p{self._page_id}b0") = obj_scr end ##################################################################### # General Setters and Getters ##################################################################### + #- ------------------------------------------------------------# + # Internal utility functions + # + # Mapping of virtual attributes + # + #- ------------------------------------------------------------# + # `member` virtual getter + #- ------------------------------------------------------------# + def member(k) + import string + import introspect + + if string.startswith(k, "set_") || string.startswith(k, "get_") return end + + # if attribute name is in ignore list, abort + # if self._attr_ignore.find(k) != nil return end + # we don't need an ignore list for pages + + # first check if there is a method named `get_X()` + var f = introspect.get(self, "get_" + k) # call self method + if type(f) == 'function' + # print(f">>>: getmember local method get_{k}") + return f(self) + end + + # fallback to exception if attribute unknown or not a function + return module("undefined") + end + #==================================================================== # retrieve lvgl screen object for this page #==================================================================== @@ -2416,34 +2446,39 @@ class lvh_page #==================================================================== # `delete` special attribute used to delete the object #==================================================================== - # def set_delete(v) - # raise "type_error", "you cannot assign to 'delete'" - # end - # def get_delete() - # self._delete() - # return def () end - # end - def delete() + def get_clear() + self._clear() + return def () end + end + def _clear() # iterate on all objects and try to delete # we first get a copy of all ids so we can delete and continue iterating # without fearing about an infinite loop - var page_ids = [] + var ids = [] for id: self._obj_id.keys() - page_ids.push(id) + ids.push(id) end # we iterate until the array is empty var idx = 0 - while idx < size(page_ids) - var page_id = page_ids[idx] + while idx < size(ids) + var page_id = ids[idx] if (page_id != 0) && self._obj_id.contains(page_id) # first check if the id is still in the page - it could have been already removed if it's a sub-object - self._obj_id[page_id].delete() + self._obj_id[page_id]._delete() end idx += 1 end self._obj_id = {} # clear map - # remove from page + end + def get_delete() + self._delete() + return def () end + end + def _delete() + # remove from page, also change page if this is the current one self._hm._remove_page(self._page_id) + # clear content + self._clear() end #==================================================================== @@ -2790,37 +2825,59 @@ class HASPmota # Execute a page changing action from string `action` # # Arg1 `action` can be `prev`, `next`, `back` or `p` - # Returns: nil + # of `delete` if we are deleting the current page + # duration: in ms, default 500 ms + # anim: -1 right to left, 1 left to right (default), `nil` auto, 0 none + # Returns: the target page object if changed, or `nil` if still on same page #==================================================================== - def page_show(action) + def page_show(action, anim, duration) + # resolve between page numbers + # p1 is either a number or nil (stored value) + # p2 is the default value + # l is the list of page ids + def to_page_resolve(p1, p_def, l) + if (p1 != nil) && (l.find(p1) != nil) + return p1 + else + return p_def + end + end # action can be `prev`, `next`, `back`, or `p` like `p1` var to_page = nil - var cur_page = self.lvh_pages[self.lvh_page_cur_idx] + var cur_page = self.get_page_cur() var sorted_pages_list = self.pages_list_sorted(self.lvh_page_cur_idx) - if size(sorted_pages_list) <= 1 return end # if only 1 page, do nothing + + if size(sorted_pages_list) <= 1 # if only 1 page, do nothing + return nil + end + # handle prev/next/back values # get the corresponding value from page object, # if absent, revert to next page, previous page and page 1 # print("sorted_pages_list",sorted_pages_list) if action == 'prev' - to_page = int(cur_page.prev) - if to_page == nil to_page = sorted_pages_list[-1] end # if no prev, take the previous page + to_page = to_page_resolve(int(cur_page.prev), sorted_pages_list[-1], sorted_pages_list) elif action == 'next' - to_page = int(cur_page.next) - if to_page == nil to_page = sorted_pages_list[1] end # if no next, take the next page + to_page = to_page_resolve(int(cur_page.next), sorted_pages_list[1], sorted_pages_list) elif action == 'back' - to_page = int(cur_page.back) - if to_page == nil # if no back, take first page - to_page = self.pages_list_sorted(nil)[0] - end + to_page = to_page_resolve(int(cur_page.back), self.pages_list_sorted(nil)[0], sorted_pages_list) + elif action == 'delete' + to_page = to_page_resolve(int(cur_page.back), self.pages_list_sorted(nil)[0], sorted_pages_list) + if (to_page == cur_page.id()) + to_page = to_page_resolve(int(cur_page.next), sorted_pages_list[1], sorted_pages_list) + end elif self.re_page_target.match(action) # action is supposed to be `p` format - to_page = int(action[1..-1]) # just skip first char and convert the rest to a string + to_page = to_page_resolve(int(action[1..-1]), nil #-default to nil-#, sorted_pages_list) end # print("to_page=",to_page) - if to_page != nil && to_page > 0 # we have a target - self.lvh_pages[to_page].show() # switch to the target page + if (to_page != nil) && (to_page > 0) # we have a target + var to_page_obj = self.lvh_pages[to_page] + if (to_page_obj != nil) + to_page_obj.show(anim, duration) + end + return to_page_obj end end @@ -2861,11 +2918,20 @@ class HASPmota #==================================================================== def _remove_page(page_id) # check if we remove the active page - # TODO XXX + var cur_page_id = self.get_page_cur().id() + if (page_id == cur_page_id) + # if we try to delete the current page, move do main page + var to_page_obj = self.page_show("delete", 0, 0 #-no animation-#) # get the target page as result + if (to_page_obj == nil) # we didn't change page + return + end + end # remove object from page object if self.lvh_pages.contains(page_id) self.lvh_pages.remove(page_id) end + # remove global for page + global.(f"p{page_id}") = nil end #==================================================================== diff --git a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h index b8aee1c67..cb246dc39 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h +++ b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h @@ -4,8 +4,8 @@ \********************************************************************/ #include "be_constobj.h" extern const bclass be_class_lvh_root; -// compact class 'lvh_root' ktab size: 63, total: 95 (saved 256 bytes) -static const bvalue be_ktab_class_lvh_root[63] = { +// compact class 'lvh_root' ktab size: 65, total: 98 (saved 264 bytes) +static const bvalue be_ktab_class_lvh_root[65] = { /* K0 */ be_nested_str_weak(_val_rule_formula), /* K1 */ be_nested_str_weak(_val_rule), /* K2 */ be_nested_str_weak(_page), @@ -43,32 +43,34 @@ static const bvalue be_ktab_class_lvh_root[63] = { /* K34 */ be_nested_str_weak(remove_val_rule), /* K35 */ be_nested_str_weak(tasmota), /* K36 */ be_nested_str_weak(add_rule), - /* K37 */ be_nested_str_weak(get_text), - /* K38 */ be_const_class(be_class_lvh_root), - /* K39 */ be_nested_str_weak(_X23), - /* K40 */ be_nested_str_weak(color), - /* K41 */ be_nested_str_weak(introspect), - /* K42 */ be_nested_str_weak(COLOR_), - /* K43 */ be_nested_str_weak(toupper), - /* K44 */ be_nested_str_weak(get), - /* K45 */ be_nested_str_weak(_val_rule_function), - /* K46 */ be_nested_str_weak(_val), - /* K47 */ be_nested_str_weak(set_val), - /* K48 */ be_nested_str_weak(resize), - /* K49 */ be_nested_str_weak(_digit2part), - /* K50 */ be_nested_str_weak(_digit2state), - /* K51 */ be_nested_str_weak(invalid_X20style_X20suffix_X20_X2502i), - /* K52 */ be_nested_str_weak(value_error), - /* K53 */ be_nested_str_weak(remove_rule), - /* K54 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20run_X20self_X2E_val_rule_function_X20_X2D_X20_X25s_X20_X28_X25s_X29), - /* K55 */ be_nested_str_weak(val), - /* K56 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20run_X20self_X2E_text_rule_function_X20_X2D_X20_X25s_X20_X28_X25s_X29), - /* K57 */ be_nested_str_weak(), - /* K58 */ be_nested_str_weak(text), - /* K59 */ be_nested_str_weak(remove_text_rule), - /* K60 */ be_nested_str_weak(type_error), - /* K61 */ be_nested_str_weak(you_X20cannot_X20assign_X20to_X20_X27delete_X27), - /* K62 */ be_nested_str_weak(set_text), + /* K37 */ be_nested_str_weak(remove_obj), + /* K38 */ be_nested_str_weak(id), + /* K39 */ be_nested_str_weak(get_text), + /* K40 */ be_const_class(be_class_lvh_root), + /* K41 */ be_nested_str_weak(_X23), + /* K42 */ be_nested_str_weak(color), + /* K43 */ be_nested_str_weak(introspect), + /* K44 */ be_nested_str_weak(COLOR_), + /* K45 */ be_nested_str_weak(toupper), + /* K46 */ be_nested_str_weak(get), + /* K47 */ be_nested_str_weak(_val_rule_function), + /* K48 */ be_nested_str_weak(_val), + /* K49 */ be_nested_str_weak(set_val), + /* K50 */ be_nested_str_weak(resize), + /* K51 */ be_nested_str_weak(_digit2part), + /* K52 */ be_nested_str_weak(_digit2state), + /* K53 */ be_nested_str_weak(invalid_X20style_X20suffix_X20_X2502i), + /* K54 */ be_nested_str_weak(value_error), + /* K55 */ be_nested_str_weak(remove_rule), + /* K56 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20run_X20self_X2E_val_rule_function_X20_X2D_X20_X25s_X20_X28_X25s_X29), + /* K57 */ be_nested_str_weak(val), + /* K58 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20run_X20self_X2E_text_rule_function_X20_X2D_X20_X25s_X20_X28_X25s_X29), + /* K59 */ be_nested_str_weak(), + /* K60 */ be_nested_str_weak(text), + /* K61 */ be_nested_str_weak(remove_text_rule), + /* K62 */ be_nested_str_weak(type_error), + /* K63 */ be_nested_str_weak(you_X20cannot_X20assign_X20to_X20_X27delete_X27), + /* K64 */ be_nested_str_weak(set_text), }; @@ -625,7 +627,7 @@ be_local_closure(class_lvh_root_set_val_rule, /* name */ ********************************************************************/ be_local_closure(class_lvh_root__delete, /* name */ be_nested_proto( - 1, /* nstack */ + 4, /* nstack */ 1, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -636,8 +638,12 @@ be_local_closure(class_lvh_root__delete, /* name */ &be_ktab_class_lvh_root, /* shared constants */ be_str_weak(_delete), &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C040325, // 0001 GETMET R1 R1 K37 + 0x880C0126, // 0002 GETMBR R3 R0 K38 + 0x7C040400, // 0003 CALL R1 2 + 0x80000000, // 0004 RET 0 }) ) ); @@ -661,7 +667,7 @@ be_local_closure(class_lvh_root_get_value_str, /* name */ be_str_weak(get_value_str), &be_const_str_solidified, ( &(const binstruction[ 3]) { /* code */ - 0x8C040125, // 0000 GETMET R1 R0 K37 + 0x8C040127, // 0000 GETMET R1 R0 K39 0x7C040200, // 0001 CALL R1 1 0x80040200, // 0002 RET 1 R1 }) @@ -785,17 +791,17 @@ be_local_closure(class_lvh_root_parse_color, /* name */ be_str_weak(parse_color), &be_const_str_solidified, ( &(const binstruction[40]) { /* code */ - 0x58040026, // 0000 LDCONST R1 K38 + 0x58040028, // 0000 LDCONST R1 K40 0x84080000, // 0001 CLOSURE R2 P0 0x600C0008, // 0002 GETGBL R3 G8 0x5C100000, // 0003 MOVE R4 R0 0x7C0C0200, // 0004 CALL R3 1 0x5C000600, // 0005 MOVE R0 R3 0x940C0112, // 0006 GETIDX R3 R0 K18 - 0x1C0C0727, // 0007 EQ R3 R3 K39 + 0x1C0C0729, // 0007 EQ R3 R3 K41 0x780E0007, // 0008 JMPF R3 #0011 0xB80E1000, // 0009 GETNGBL R3 K8 - 0x8C0C0728, // 000A GETMET R3 R3 K40 + 0x8C0C072A, // 000A GETMET R3 R3 K42 0x5C140400, // 000B MOVE R5 R2 0x5C180000, // 000C MOVE R6 R0 0x7C140200, // 000D CALL R5 1 @@ -803,12 +809,12 @@ be_local_closure(class_lvh_root_parse_color, /* name */ 0x80040600, // 000F RET 1 R3 0x70020011, // 0010 JMP #0023 0xA40E1A00, // 0011 IMPORT R3 K13 - 0xA4125200, // 0012 IMPORT R4 K41 - 0x8C14072B, // 0013 GETMET R5 R3 K43 + 0xA4125600, // 0012 IMPORT R4 K43 + 0x8C14072D, // 0013 GETMET R5 R3 K45 0x5C1C0000, // 0014 MOVE R7 R0 0x7C140400, // 0015 CALL R5 2 - 0x00165405, // 0016 ADD R5 K42 R5 - 0x8C18092C, // 0017 GETMET R6 R4 K44 + 0x00165805, // 0016 ADD R5 K44 R5 + 0x8C18092E, // 0017 GETMET R6 R4 K46 0xB8221000, // 0018 GETNGBL R8 K8 0x5C240A00, // 0019 MOVE R9 R5 0x7C180600, // 001A CALL R6 3 @@ -816,12 +822,12 @@ be_local_closure(class_lvh_root_parse_color, /* name */ 0x201C0C07, // 001C NE R7 R6 R7 0x781E0004, // 001D JMPF R7 #0023 0xB81E1000, // 001E GETNGBL R7 K8 - 0x8C1C0F28, // 001F GETMET R7 R7 K40 + 0x8C1C0F2A, // 001F GETMET R7 R7 K42 0x5C240C00, // 0020 MOVE R9 R6 0x7C1C0400, // 0021 CALL R7 2 0x80040E00, // 0022 RET 1 R7 0xB80E1000, // 0023 GETNGBL R3 K8 - 0x8C0C0728, // 0024 GETMET R3 R3 K40 + 0x8C0C072A, // 0024 GETMET R3 R3 K42 0x58140012, // 0025 LDCONST R5 K18 0x7C0C0400, // 0026 CALL R3 2 0x80040600, // 0027 RET 1 R3 @@ -861,7 +867,7 @@ be_local_closure(class_lvh_root_set_val_rule_formula, /* name */ 0x7C0C0200, // 000A CALL R3 1 0x5C100600, // 000B MOVE R4 R3 0x7C100000, // 000C CALL R4 0 - 0x90025A04, // 000D SETMBR R0 K45 R4 + 0x90025E04, // 000D SETMBR R0 K47 R4 0xA8040001, // 000E EXBLK 1 1 0x7002000B, // 000F JMP #001C 0xAC0C0002, // 0010 CATCH R3 0 2 @@ -900,12 +906,12 @@ be_local_closure(class_lvh_root_post_config, /* name */ be_str_weak(post_config), &be_const_str_solidified, ( &(const binstruction[ 8]) { /* code */ - 0x8804012E, // 0000 GETMBR R1 R0 K46 + 0x88040130, // 0000 GETMBR R1 R0 K48 0x4C080000, // 0001 LDNIL R2 0x20040202, // 0002 NE R1 R1 R2 0x78060002, // 0003 JMPF R1 #0007 - 0x8C04012F, // 0004 GETMET R1 R0 K47 - 0x880C012E, // 0005 GETMBR R3 R0 K46 + 0x8C040131, // 0004 GETMET R1 R0 K49 + 0x880C0130, // 0005 GETMBR R3 R0 K48 0x7C040400, // 0006 CALL R1 2 0x80000000, // 0007 RET 0 }) @@ -931,7 +937,7 @@ be_local_closure(class_lvh_root_remove_trailing_zeroes, /* name */ be_str_weak(remove_trailing_zeroes), &be_const_str_solidified, ( &(const binstruction[24]) { /* code */ - 0x58040026, // 0000 LDCONST R1 K38 + 0x58040028, // 0000 LDCONST R1 K40 0x6008000C, // 0001 GETGBL R2 G12 0x5C0C0000, // 0002 MOVE R3 R0 0x7C080200, // 0003 CALL R2 1 @@ -948,7 +954,7 @@ be_local_closure(class_lvh_root_remove_trailing_zeroes, /* name */ 0x7001FFF5, // 000E JMP #0005 0x24100712, // 000F GT R4 R3 K18 0x78120005, // 0010 JMPF R4 #0017 - 0x8C100130, // 0011 GETMET R4 R0 K48 + 0x8C100132, // 0011 GETMET R4 R0 K50 0x6018000C, // 0012 GETGBL R6 G12 0x5C1C0000, // 0013 MOVE R7 R0 0x7C180200, // 0014 CALL R6 1 @@ -1042,11 +1048,11 @@ be_local_closure(class_lvh_root_digits_to_style, /* name */ 0x28140512, // 000B GE R5 R2 K18 0x78160008, // 000C JMPF R5 #0016 0x6014000C, // 000D GETGBL R5 G12 - 0x88180131, // 000E GETMBR R6 R0 K49 + 0x88180133, // 000E GETMBR R6 R0 K51 0x7C140200, // 000F CALL R5 1 0x14140405, // 0010 LT R5 R2 R5 0x78160003, // 0011 JMPF R5 #0016 - 0x88140131, // 0012 GETMBR R5 R0 K49 + 0x88140133, // 0012 GETMBR R5 R0 K51 0x94140A02, // 0013 GETIDX R5 R5 R2 0x30100805, // 0014 OR R4 R4 R5 0x70020000, // 0015 JMP #0017 @@ -1054,11 +1060,11 @@ be_local_closure(class_lvh_root_digits_to_style, /* name */ 0x28140712, // 0017 GE R5 R3 K18 0x78160008, // 0018 JMPF R5 #0022 0x6014000C, // 0019 GETGBL R5 G12 - 0x88180132, // 001A GETMBR R6 R0 K50 + 0x88180134, // 001A GETMBR R6 R0 K52 0x7C140200, // 001B CALL R5 1 0x14140605, // 001C LT R5 R3 R5 0x78160003, // 001D JMPF R5 #0022 - 0x88140132, // 001E GETMBR R5 R0 K50 + 0x88140134, // 001E GETMBR R5 R0 K52 0x94140A03, // 001F GETIDX R5 R5 R3 0x30100805, // 0020 OR R4 R4 R5 0x70020000, // 0021 JMP #0023 @@ -1067,10 +1073,10 @@ be_local_closure(class_lvh_root_digits_to_style, /* name */ 0x1C140805, // 0024 EQ R5 R4 R5 0x78160004, // 0025 JMPF R5 #002B 0x60140018, // 0026 GETGBL R5 G24 - 0x58180033, // 0027 LDCONST R6 K51 + 0x58180035, // 0027 LDCONST R6 K53 0x5C1C0200, // 0028 MOVE R7 R1 0x7C140400, // 0029 CALL R5 2 - 0xB0066805, // 002A RAISE 1 K52 R5 + 0xB0066C05, // 002A RAISE 1 K54 R5 0x80040800, // 002B RET 1 R4 }) ) @@ -1100,7 +1106,7 @@ be_local_closure(class_lvh_root_remove_val_rule, /* name */ 0x20040202, // 0002 NE R1 R1 R2 0x78060004, // 0003 JMPF R1 #0009 0xB8064600, // 0004 GETNGBL R1 K35 - 0x8C040335, // 0005 GETMET R1 R1 K53 + 0x8C040337, // 0005 GETMET R1 R1 K55 0x880C0101, // 0006 GETMBR R3 R0 K1 0x5C100000, // 0007 MOVE R4 R0 0x7C040600, // 0008 CALL R1 3 @@ -1136,7 +1142,7 @@ be_local_closure(class_lvh_root_val_rule_matched, /* name */ 0x780E0001, // 0005 JMPF R3 #0008 0x500C0000, // 0006 LDBOOL R3 0 0 0x80040600, // 0007 RET 1 R3 - 0x880C012D, // 0008 GETMBR R3 R0 K45 + 0x880C012F, // 0008 GETMBR R3 R0 K47 0x4C100000, // 0009 LDNIL R4 0x20100604, // 000A NE R4 R3 R4 0x78120011, // 000B JMPF R4 #001E @@ -1151,7 +1157,7 @@ be_local_closure(class_lvh_root_val_rule_matched, /* name */ 0x70020007, // 0014 JMP #001D 0x60180001, // 0015 GETGBL R6 G1 0x601C0018, // 0016 GETGBL R7 G24 - 0x58200036, // 0017 LDCONST R8 K54 + 0x58200038, // 0017 LDCONST R8 K56 0x5C240800, // 0018 MOVE R9 R4 0x5C280A00, // 0019 MOVE R10 R5 0x7C1C0600, // 001A CALL R7 3 @@ -1161,7 +1167,7 @@ be_local_closure(class_lvh_root_val_rule_matched, /* name */ 0x60100009, // 001E GETGBL R4 G9 0x5C140400, // 001F MOVE R5 R2 0x7C100200, // 0020 CALL R4 1 - 0x90026E04, // 0021 SETMBR R0 K55 R4 + 0x90027204, // 0021 SETMBR R0 K57 R4 0x50100000, // 0022 LDBOOL R4 0 0 0x80040800, // 0023 RET 1 R4 }) @@ -1211,7 +1217,7 @@ be_local_closure(class_lvh_root_text_rule_matched, /* name */ 0x70020007, // 0015 JMP #001E 0x60140001, // 0016 GETGBL R5 G1 0x60180018, // 0017 GETGBL R6 G24 - 0x581C0038, // 0018 LDCONST R7 K56 + 0x581C003A, // 0018 LDCONST R7 K58 0x5C200600, // 0019 MOVE R8 R3 0x5C240800, // 001A MOVE R9 R4 0x7C180600, // 001B CALL R6 3 @@ -1230,8 +1236,8 @@ be_local_closure(class_lvh_root_text_rule_matched, /* name */ 0x7C100400, // 0028 CALL R4 2 0x5C0C0800, // 0029 MOVE R3 R4 0x70020000, // 002A JMP #002C - 0x580C0039, // 002B LDCONST R3 K57 - 0x90027403, // 002C SETMBR R0 K58 R3 + 0x580C003B, // 002B LDCONST R3 K59 + 0x90027803, // 002C SETMBR R0 K60 R3 0x50100000, // 002D LDBOOL R4 0 0 0x80040800, // 002E RET 1 R4 }) @@ -1262,7 +1268,7 @@ be_local_closure(class_lvh_root_is_color_attribute, /* name */ 0x60140008, // 0002 GETGBL R5 G8 0x5C180200, // 0003 MOVE R6 R1 0x7C140200, // 0004 CALL R5 1 - 0x58180028, // 0005 LDCONST R6 K40 + 0x5818002A, // 0005 LDCONST R6 K42 0x7C0C0600, // 0006 CALL R3 3 0x80040600, // 0007 RET 1 R3 }) @@ -1338,7 +1344,7 @@ be_local_closure(class_lvh_root_set_text_rule, /* name */ be_str_weak(set_text_rule), &be_const_str_solidified, ( &(const binstruction[14]) { /* code */ - 0x8C08013B, // 0000 GETMET R2 R0 K59 + 0x8C08013D, // 0000 GETMET R2 R0 K61 0x7C080200, // 0001 CALL R2 1 0x60080008, // 0002 GETGBL R2 G8 0x5C0C0200, // 0003 MOVE R3 R1 @@ -1380,7 +1386,7 @@ be_local_closure(class_lvh_root_remove_text_rule, /* name */ 0x20040202, // 0002 NE R1 R1 R2 0x78060004, // 0003 JMPF R1 #0009 0xB8064600, // 0004 GETNGBL R1 K35 - 0x8C040335, // 0005 GETMET R1 R1 K53 + 0x8C040337, // 0005 GETMET R1 R1 K55 0x880C0121, // 0006 GETMBR R3 R0 K33 0x5C100000, // 0007 MOVE R4 R0 0x7C040600, // 0008 CALL R1 3 @@ -1408,7 +1414,7 @@ be_local_closure(class_lvh_root_set_delete, /* name */ be_str_weak(set_delete), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ - 0xB006793D, // 0000 RAISE 1 K60 K61 + 0xB0067D3F, // 0000 RAISE 1 K62 K63 0x80000000, // 0001 RET 0 }) ) @@ -1433,7 +1439,7 @@ be_local_closure(class_lvh_root_set_value_str, /* name */ be_str_weak(set_value_str), &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C08013E, // 0000 GETMET R2 R0 K62 + 0x8C080140, // 0000 GETMET R2 R0 K64 0x5C100200, // 0001 MOVE R4 R1 0x7C080400, // 0002 CALL R2 2 0x80000000, // 0003 RET 0 @@ -1572,7 +1578,7 @@ be_local_class(lvh_root, })), be_str_weak(lvh_root) ); -// compact class 'lvh_obj' ktab size: 136, total: 285 (saved 1192 bytes) +// compact class 'lvh_obj' ktab size: 136, total: 283 (saved 1176 bytes) static const bvalue be_ktab_class_lvh_obj[136] = { /* K0 */ be_nested_str_weak(_action), /* K1 */ be_nested_str_weak(_lv_label), @@ -1608,81 +1614,81 @@ static const bvalue be_ktab_class_lvh_obj[136] = { /* K31 */ be_nested_str_weak(remove_val_rule), /* K32 */ be_nested_str_weak(remove_text_rule), /* K33 */ be_nested_str_weak(del), - /* K34 */ be_nested_str_weak(remove_obj), - /* K35 */ be_nested_str_weak(id), - /* K36 */ be_nested_str_weak(get_text_font), - /* K37 */ be_nested_str_weak(get_style_radius), - /* K38 */ be_nested_str_weak(set_text_color), - /* K39 */ be_nested_str_weak(get_style_text_color), - /* K40 */ be_nested_str_weak(get_x), - /* K41 */ be_nested_str_weak(get_long_mode), - /* K42 */ be_nested_str_weak(_val), - /* K43 */ be_nested_str_weak(set_value), - /* K44 */ be_nested_str_weak(set_enabled), - /* K45 */ be_nested_str_weak(string), - /* K46 */ be_nested_str_weak(startswith), - /* K47 */ be_nested_str_weak(set_), - /* K48 */ be_nested_str_weak(get_), - /* K49 */ be_const_int(3), - /* K50 */ be_nested_str_weak(byte), - /* K51 */ be_const_int(2147483647), - /* K52 */ be_nested_str_weak(digits_to_style), - /* K53 */ be_nested_str_weak(_attr_ignore), - /* K54 */ be_nested_str_weak(find), - /* K55 */ be_nested_str_weak(get), - /* K56 */ be_nested_str_weak(function), - /* K57 */ be_nested_str_weak(_attr_map), - /* K58 */ be_nested_str_weak(get_style_), - /* K59 */ be_nested_str_weak(undefined), - /* K60 */ be_nested_str_weak(set_style_pad_top), - /* K61 */ be_nested_str_weak(clear_state), - /* K62 */ be_nested_str_weak(add_state), - /* K63 */ be_nested_str_weak(check_label), - /* K64 */ be_nested_str_weak(set_x), - /* K65 */ be_nested_str_weak(init), - /* K66 */ be_nested_str_weak(STATE_CHECKED), - /* K67 */ be_nested_str_weak(parse_font), - /* K68 */ be_nested_str_weak(set_style_text_font), - /* K69 */ be_nested_str_weak(get_enabled), - /* K70 */ be_nested_str_weak(set_style_pad_right), - /* K71 */ be_nested_str_weak(), - /* K72 */ be_nested_str_weak(real), - /* K73 */ be_nested_str_weak(math), - /* K74 */ be_nested_str_weak(round), - /* K75 */ be_nested_str_weak(endswith), - /* K76 */ be_nested_str_weak(_X25), - /* K77 */ be_nested_str_weak(pct), - /* K78 */ be_nested_str_weak(is_color_attribute), - /* K79 */ be_nested_str_weak(set_style_), - /* K80 */ be_nested_str_weak(HSP_X3A_X20unknown_X20attribute_X3A), - /* K81 */ be_nested_str_weak(set_text_font), - /* K82 */ be_nested_str_weak(toupper), - /* K83 */ be_nested_str_weak(TRUE), - /* K84 */ be_nested_str_weak(FALSE), - /* K85 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), - /* K86 */ be_nested_str_weak(get_style_text_align), - /* K87 */ be_nested_str_weak(TEXT_ALIGN_LEFT), - /* K88 */ be_nested_str_weak(left), - /* K89 */ be_nested_str_weak(TEXT_ALIGN_CENTER), - /* K90 */ be_nested_str_weak(center), - /* K91 */ be_nested_str_weak(TEXT_ALIGN_RIGHT), - /* K92 */ be_nested_str_weak(right), - /* K93 */ be_nested_str_weak(get_style_pad_top), - /* K94 */ be_nested_str_weak(set_style_radius), - /* K95 */ be_nested_str_weak(get_code), - /* K96 */ be_nested_str_weak(action), - /* K97 */ be_nested_str_weak(EVENT_CLICKED), - /* K98 */ be_nested_str_weak(tasmota), - /* K99 */ be_nested_str_weak(set_timer), - /* K100 */ be_nested_str_weak(_event_map), - /* K101 */ be_nested_str_weak(json), - /* K102 */ be_nested_str_weak(EVENT_VALUE_CHANGED), - /* K103 */ be_nested_str_weak(module), - /* K104 */ be_nested_str_weak(_X2C_X22val_X22_X3A_X25s), - /* K105 */ be_nested_str_weak(dump), - /* K106 */ be_nested_str_weak(_X2C_X22text_X22_X3A_X25s), - /* K107 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25ib_X25i_X22_X3A_X7B_X22event_X22_X3A_X22_X25s_X22_X25s_X7D_X7D_X7D), - /* K108 */ be_nested_str_weak(_page_id), + /* K34 */ be_nested_str_weak(_delete), + /* K35 */ be_nested_str_weak(get_text_font), + /* K36 */ be_nested_str_weak(get_style_radius), + /* K37 */ be_nested_str_weak(set_text_color), + /* K38 */ be_nested_str_weak(get_style_text_color), + /* K39 */ be_nested_str_weak(get_x), + /* K40 */ be_nested_str_weak(get_long_mode), + /* K41 */ be_nested_str_weak(_val), + /* K42 */ be_nested_str_weak(set_value), + /* K43 */ be_nested_str_weak(set_enabled), + /* K44 */ be_nested_str_weak(string), + /* K45 */ be_nested_str_weak(startswith), + /* K46 */ be_nested_str_weak(set_), + /* K47 */ be_nested_str_weak(get_), + /* K48 */ be_const_int(3), + /* K49 */ be_nested_str_weak(byte), + /* K50 */ be_const_int(2147483647), + /* K51 */ be_nested_str_weak(digits_to_style), + /* K52 */ be_nested_str_weak(_attr_ignore), + /* K53 */ be_nested_str_weak(find), + /* K54 */ be_nested_str_weak(get), + /* K55 */ be_nested_str_weak(function), + /* K56 */ be_nested_str_weak(_attr_map), + /* K57 */ be_nested_str_weak(get_style_), + /* K58 */ be_nested_str_weak(undefined), + /* K59 */ be_nested_str_weak(set_style_pad_top), + /* K60 */ be_nested_str_weak(clear_state), + /* K61 */ be_nested_str_weak(add_state), + /* K62 */ be_nested_str_weak(check_label), + /* K63 */ be_nested_str_weak(set_x), + /* K64 */ be_nested_str_weak(init), + /* K65 */ be_nested_str_weak(STATE_CHECKED), + /* K66 */ be_nested_str_weak(parse_font), + /* K67 */ be_nested_str_weak(set_style_text_font), + /* K68 */ be_nested_str_weak(get_enabled), + /* K69 */ be_nested_str_weak(set_style_pad_right), + /* K70 */ be_nested_str_weak(), + /* K71 */ be_nested_str_weak(real), + /* K72 */ be_nested_str_weak(math), + /* K73 */ be_nested_str_weak(round), + /* K74 */ be_nested_str_weak(endswith), + /* K75 */ be_nested_str_weak(_X25), + /* K76 */ be_nested_str_weak(pct), + /* K77 */ be_nested_str_weak(is_color_attribute), + /* K78 */ be_nested_str_weak(set_style_), + /* K79 */ be_nested_str_weak(HSP_X3A_X20unknown_X20attribute_X3A), + /* K80 */ be_nested_str_weak(set_text_font), + /* K81 */ be_nested_str_weak(toupper), + /* K82 */ be_nested_str_weak(TRUE), + /* K83 */ be_nested_str_weak(FALSE), + /* K84 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), + /* K85 */ be_nested_str_weak(get_style_text_align), + /* K86 */ be_nested_str_weak(TEXT_ALIGN_LEFT), + /* K87 */ be_nested_str_weak(left), + /* K88 */ be_nested_str_weak(TEXT_ALIGN_CENTER), + /* K89 */ be_nested_str_weak(center), + /* K90 */ be_nested_str_weak(TEXT_ALIGN_RIGHT), + /* K91 */ be_nested_str_weak(right), + /* K92 */ be_nested_str_weak(get_style_pad_top), + /* K93 */ be_nested_str_weak(set_style_radius), + /* K94 */ be_nested_str_weak(get_code), + /* K95 */ be_nested_str_weak(action), + /* K96 */ be_nested_str_weak(EVENT_CLICKED), + /* K97 */ be_nested_str_weak(tasmota), + /* K98 */ be_nested_str_weak(set_timer), + /* K99 */ be_nested_str_weak(_event_map), + /* K100 */ be_nested_str_weak(json), + /* K101 */ be_nested_str_weak(EVENT_VALUE_CHANGED), + /* K102 */ be_nested_str_weak(module), + /* K103 */ be_nested_str_weak(_X2C_X22val_X22_X3A_X25s), + /* K104 */ be_nested_str_weak(dump), + /* K105 */ be_nested_str_weak(_X2C_X22text_X22_X3A_X25s), + /* K106 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25ib_X25i_X22_X3A_X7B_X22event_X22_X3A_X22_X25s_X22_X25s_X7D_X7D_X7D), + /* K107 */ be_nested_str_weak(_page_id), + /* K108 */ be_nested_str_weak(id), /* K109 */ be_nested_str_weak(get_style_pad_bottom), /* K110 */ be_nested_str_weak(get_y), /* K111 */ be_nested_str_weak(set_style_pad_bottom), @@ -2120,7 +2126,7 @@ be_local_closure(class_lvh_obj_post_init, /* name */ ********************************************************************/ be_local_closure(class_lvh_obj__delete, /* name */ be_nested_proto( - 4, /* nstack */ + 3, /* nstack */ 1, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -2131,7 +2137,7 @@ be_local_closure(class_lvh_obj__delete, /* name */ &be_ktab_class_lvh_obj, /* shared constants */ be_str_weak(_delete), &be_const_str_solidified, - ( &(const binstruction[23]) { /* code */ + ( &(const binstruction[24]) { /* code */ 0x8C04011F, // 0000 GETMET R1 R0 K31 0x7C040200, // 0001 CALL R1 1 0x8C040120, // 0002 GETMET R1 R0 K32 @@ -2150,11 +2156,12 @@ be_local_closure(class_lvh_obj__delete, /* name */ 0x7C040200, // 000F CALL R1 1 0x4C040000, // 0010 LDNIL R1 0x90020601, // 0011 SETMBR R0 K3 R1 - 0x88040115, // 0012 GETMBR R1 R0 K21 - 0x8C040322, // 0013 GETMET R1 R1 K34 - 0x880C0123, // 0014 GETMBR R3 R0 K35 - 0x7C040400, // 0015 CALL R1 2 - 0x80000000, // 0016 RET 0 + 0x60040003, // 0012 GETGBL R1 G3 + 0x5C080000, // 0013 MOVE R2 R0 + 0x7C040200, // 0014 CALL R1 1 + 0x8C040322, // 0015 GETMET R1 R1 K34 + 0x7C040200, // 0016 CALL R1 1 + 0x80000000, // 0017 RET 0 }) ) ); @@ -2178,7 +2185,7 @@ be_local_closure(class_lvh_obj_get_value_font, /* name */ be_str_weak(get_value_font), &be_const_str_solidified, ( &(const binstruction[ 3]) { /* code */ - 0x8C040124, // 0000 GETMET R1 R0 K36 + 0x8C040123, // 0000 GETMET R1 R0 K35 0x7C040200, // 0001 CALL R1 1 0x80040200, // 0002 RET 1 R1 }) @@ -2209,7 +2216,7 @@ be_local_closure(class_lvh_obj_get_radius2, /* name */ 0x20040202, // 0002 NE R1 R1 R2 0x78060007, // 0003 JMPF R1 #000C 0x88040103, // 0004 GETMBR R1 R0 K3 - 0x8C040325, // 0005 GETMET R1 R1 K37 + 0x8C040324, // 0005 GETMET R1 R1 K36 0x880C0107, // 0006 GETMBR R3 R0 K7 0xB8120A00, // 0007 GETNGBL R4 K5 0x88100909, // 0008 GETMBR R4 R4 K9 @@ -2240,7 +2247,7 @@ be_local_closure(class_lvh_obj_set_value_color, /* name */ be_str_weak(set_value_color), &be_const_str_solidified, ( &(const binstruction[ 5]) { /* code */ - 0x8C0C0126, // 0000 GETMET R3 R0 K38 + 0x8C0C0125, // 0000 GETMET R3 R0 K37 0x5C140200, // 0001 MOVE R5 R1 0x5C180400, // 0002 MOVE R6 R2 0x7C0C0600, // 0003 CALL R3 3 @@ -2269,7 +2276,7 @@ be_local_closure(class_lvh_obj_get_text_color, /* name */ &be_const_str_solidified, ( &(const binstruction[ 5]) { /* code */ 0x88080103, // 0000 GETMBR R2 R0 K3 - 0x8C080527, // 0001 GETMET R2 R2 K39 + 0x8C080526, // 0001 GETMET R2 R2 K38 0x5C100200, // 0002 MOVE R4 R1 0x7C080400, // 0003 CALL R2 2 0x80040400, // 0004 RET 1 R2 @@ -2297,7 +2304,7 @@ be_local_closure(class_lvh_obj_get_value_ofs_x, /* name */ &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ 0x88040101, // 0000 GETMBR R1 R0 K1 - 0x8C040328, // 0001 GETMET R1 R1 K40 + 0x8C040327, // 0001 GETMET R1 R1 K39 0x7C040200, // 0002 CALL R1 1 0x80040200, // 0003 RET 1 R1 }) @@ -2328,7 +2335,7 @@ be_local_closure(class_lvh_obj_get_label_mode, /* name */ 0x20040202, // 0002 NE R1 R1 R2 0x78060003, // 0003 JMPF R1 #0008 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C040329, // 0005 GETMET R1 R1 K41 + 0x8C040328, // 0005 GETMET R1 R1 K40 0x7C040200, // 0006 CALL R1 1 0x80040200, // 0007 RET 1 R1 0x80000000, // 0008 RET 0 @@ -2356,14 +2363,14 @@ be_local_closure(class_lvh_obj_set_val, /* name */ &be_const_str_solidified, ( &(const binstruction[12]) { /* code */ 0xA40A1C00, // 0000 IMPORT R2 K14 - 0x90025401, // 0001 SETMBR R0 K42 R1 + 0x90025201, // 0001 SETMBR R0 K41 R1 0x8C0C050F, // 0002 GETMET R3 R2 K15 0x88140103, // 0003 GETMBR R5 R0 K3 - 0x5818002B, // 0004 LDCONST R6 K43 + 0x5818002A, // 0004 LDCONST R6 K42 0x7C0C0600, // 0005 CALL R3 3 0x780E0003, // 0006 JMPF R3 #000B 0x880C0103, // 0007 GETMBR R3 R0 K3 - 0x8C0C072B, // 0008 GETMET R3 R3 K43 + 0x8C0C072A, // 0008 GETMET R3 R3 K42 0x5C140200, // 0009 MOVE R5 R1 0x7C0C0400, // 000A CALL R3 2 0x80000000, // 000B RET 0 @@ -2390,7 +2397,7 @@ be_local_closure(class_lvh_obj_set_click, /* name */ be_str_weak(set_click), &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C08012C, // 0000 GETMET R2 R0 K44 + 0x8C08012B, // 0000 GETMET R2 R0 K43 0x5C100200, // 0001 MOVE R4 R1 0x7C080400, // 0002 CALL R2 2 0x80000000, // 0003 RET 0 @@ -2417,16 +2424,16 @@ be_local_closure(class_lvh_obj_member, /* name */ be_str_weak(member), &be_const_str_solidified, ( &(const binstruction[125]) { /* code */ - 0xA40A5A00, // 0000 IMPORT R2 K45 + 0xA40A5800, // 0000 IMPORT R2 K44 0xA40E1C00, // 0001 IMPORT R3 K14 - 0x8C10052E, // 0002 GETMET R4 R2 K46 + 0x8C10052D, // 0002 GETMET R4 R2 K45 0x5C180200, // 0003 MOVE R6 R1 - 0x581C002F, // 0004 LDCONST R7 K47 + 0x581C002E, // 0004 LDCONST R7 K46 0x7C100600, // 0005 CALL R4 3 0x74120004, // 0006 JMPT R4 #000C - 0x8C10052E, // 0007 GETMET R4 R2 K46 + 0x8C10052D, // 0007 GETMET R4 R2 K45 0x5C180200, // 0008 MOVE R6 R1 - 0x581C0030, // 0009 LDCONST R7 K48 + 0x581C002F, // 0009 LDCONST R7 K47 0x7C100600, // 000A CALL R4 3 0x78120000, // 000B JMPF R4 #000D 0x80000800, // 000C RET 0 @@ -2434,13 +2441,13 @@ be_local_closure(class_lvh_obj_member, /* name */ 0x6014000C, // 000E GETGBL R5 G12 0x5C180200, // 000F MOVE R6 R1 0x7C140200, // 0010 CALL R5 1 - 0x28140B31, // 0011 GE R5 R5 K49 + 0x28140B30, // 0011 GE R5 R5 K48 0x7816001F, // 0012 JMPF R5 #0033 - 0x8C140532, // 0013 GETMET R5 R2 K50 + 0x8C140531, // 0013 GETMET R5 R2 K49 0x541DFFFE, // 0014 LDINT R7 -1 0x941C0207, // 0015 GETIDX R7 R1 R7 0x7C140400, // 0016 CALL R5 2 - 0x8C180532, // 0017 GETMET R6 R2 K50 + 0x8C180531, // 0017 GETMET R6 R2 K49 0x5421FFFD, // 0018 LDINT R8 -2 0x94200208, // 0019 GETIDX R8 R1 R8 0x7C180400, // 001A CALL R6 2 @@ -2458,32 +2465,32 @@ be_local_closure(class_lvh_obj_member, /* name */ 0x781E000B, // 0026 JMPF R7 #0033 0x601C0009, // 0027 GETGBL R7 G9 0x5421FFFD, // 0028 LDINT R8 -2 - 0x40201133, // 0029 CONNECT R8 R8 K51 + 0x40201132, // 0029 CONNECT R8 R8 K50 0x94200208, // 002A GETIDX R8 R1 R8 0x7C1C0200, // 002B CALL R7 1 0x5421FFFC, // 002C LDINT R8 -3 0x40223008, // 002D CONNECT R8 K24 R8 0x94040208, // 002E GETIDX R1 R1 R8 - 0x8C200134, // 002F GETMET R8 R0 K52 + 0x8C200133, // 002F GETMET R8 R0 K51 0x5C280E00, // 0030 MOVE R10 R7 0x7C200400, // 0031 CALL R8 2 0x5C101000, // 0032 MOVE R4 R8 - 0x88140135, // 0033 GETMBR R5 R0 K53 - 0x8C140B36, // 0034 GETMET R5 R5 K54 + 0x88140134, // 0033 GETMBR R5 R0 K52 + 0x8C140B35, // 0034 GETMET R5 R5 K53 0x5C1C0200, // 0035 MOVE R7 R1 0x7C140400, // 0036 CALL R5 2 0x4C180000, // 0037 LDNIL R6 0x20140A06, // 0038 NE R5 R5 R6 0x78160000, // 0039 JMPF R5 #003B 0x80000A00, // 003A RET 0 - 0x8C140737, // 003B GETMET R5 R3 K55 + 0x8C140736, // 003B GETMET R5 R3 K54 0x5C1C0000, // 003C MOVE R7 R0 - 0x00226001, // 003D ADD R8 K48 R1 + 0x00225E01, // 003D ADD R8 K47 R1 0x7C140600, // 003E CALL R5 3 0x60180004, // 003F GETGBL R6 G4 0x5C1C0A00, // 0040 MOVE R7 R5 0x7C180200, // 0041 CALL R6 1 - 0x1C180D38, // 0042 EQ R6 R6 K56 + 0x1C180D37, // 0042 EQ R6 R6 K55 0x781A0009, // 0043 JMPF R6 #004E 0x5C180A00, // 0044 MOVE R6 R5 0x5C1C0000, // 0045 MOVE R7 R0 @@ -2495,8 +2502,8 @@ be_local_closure(class_lvh_obj_member, /* name */ 0x58200018, // 004B LDCONST R8 K24 0x7C180400, // 004C CALL R6 2 0x80040C00, // 004D RET 1 R6 - 0x88180139, // 004E GETMBR R6 R0 K57 - 0x8C180D36, // 004F GETMET R6 R6 K54 + 0x88180138, // 004E GETMBR R6 R0 K56 + 0x8C180D35, // 004F GETMET R6 R6 K53 0x5C200200, // 0050 MOVE R8 R1 0x5C240200, // 0051 MOVE R9 R1 0x7C180600, // 0052 CALL R6 3 @@ -2504,29 +2511,29 @@ be_local_closure(class_lvh_obj_member, /* name */ 0x4C180000, // 0054 LDNIL R6 0x1C180806, // 0055 EQ R6 R4 R6 0x781A000D, // 0056 JMPF R6 #0065 - 0x8C180737, // 0057 GETMET R6 R3 K55 + 0x8C180736, // 0057 GETMET R6 R3 K54 0x88200103, // 0058 GETMBR R8 R0 K3 - 0x00266001, // 0059 ADD R9 K48 R1 + 0x00265E01, // 0059 ADD R9 K47 R1 0x7C180600, // 005A CALL R6 3 0x5C140C00, // 005B MOVE R5 R6 0x60180004, // 005C GETGBL R6 G4 0x5C1C0A00, // 005D MOVE R7 R5 0x7C180200, // 005E CALL R6 1 - 0x1C180D38, // 005F EQ R6 R6 K56 + 0x1C180D37, // 005F EQ R6 R6 K55 0x781A0003, // 0060 JMPF R6 #0065 0x5C180A00, // 0061 MOVE R6 R5 0x881C0103, // 0062 GETMBR R7 R0 K3 0x7C180200, // 0063 CALL R6 1 0x80040C00, // 0064 RET 1 R6 - 0x8C180737, // 0065 GETMET R6 R3 K55 + 0x8C180736, // 0065 GETMET R6 R3 K54 0x88200103, // 0066 GETMBR R8 R0 K3 - 0x00267401, // 0067 ADD R9 K58 R1 + 0x00267201, // 0067 ADD R9 K57 R1 0x7C180600, // 0068 CALL R6 3 0x5C140C00, // 0069 MOVE R5 R6 0x60180004, // 006A GETGBL R6 G4 0x5C1C0A00, // 006B MOVE R7 R5 0x7C180200, // 006C CALL R6 1 - 0x1C180D38, // 006D EQ R6 R6 K56 + 0x1C180D37, // 006D EQ R6 R6 K55 0x781A0009, // 006E JMPF R6 #0079 0x5C180A00, // 006F MOVE R6 R5 0x881C0103, // 0070 GETMBR R7 R0 K3 @@ -2539,7 +2546,7 @@ be_local_closure(class_lvh_obj_member, /* name */ 0x7C180400, // 0077 CALL R6 2 0x80040C00, // 0078 RET 1 R6 0x6018000B, // 0079 GETGBL R6 G11 - 0x581C003B, // 007A LDCONST R7 K59 + 0x581C003A, // 007A LDCONST R7 K58 0x7C180200, // 007B CALL R6 1 0x80040C00, // 007C RET 1 R6 }) @@ -2570,7 +2577,7 @@ be_local_closure(class_lvh_obj_set_pad_top2, /* name */ 0x20080403, // 0002 NE R2 R2 R3 0x780A0009, // 0003 JMPF R2 #000E 0x88080103, // 0004 GETMBR R2 R0 K3 - 0x8C08053C, // 0005 GETMET R2 R2 K60 + 0x8C08053B, // 0005 GETMET R2 R2 K59 0x60100009, // 0006 GETGBL R4 G9 0x5C140200, // 0007 MOVE R5 R1 0x7C100200, // 0008 CALL R4 1 @@ -2605,13 +2612,13 @@ be_local_closure(class_lvh_obj_set_enabled, /* name */ ( &(const binstruction[13]) { /* code */ 0x78060005, // 0000 JMPF R1 #0007 0x88080103, // 0001 GETMBR R2 R0 K3 - 0x8C08053D, // 0002 GETMET R2 R2 K61 + 0x8C08053C, // 0002 GETMET R2 R2 K60 0xB8120A00, // 0003 GETNGBL R4 K5 0x8810090C, // 0004 GETMBR R4 R4 K12 0x7C080400, // 0005 CALL R2 2 0x70020004, // 0006 JMP #000C 0x88080103, // 0007 GETMBR R2 R0 K3 - 0x8C08053E, // 0008 GETMET R2 R2 K62 + 0x8C08053D, // 0008 GETMET R2 R2 K61 0xB8120A00, // 0009 GETNGBL R4 K5 0x8810090C, // 000A GETMBR R4 R4 K12 0x7C080400, // 000B CALL R2 2 @@ -2639,10 +2646,10 @@ be_local_closure(class_lvh_obj_set_value_ofs_x, /* name */ be_str_weak(set_value_ofs_x), &be_const_str_solidified, ( &(const binstruction[ 9]) { /* code */ - 0x8C08013F, // 0000 GETMET R2 R0 K63 + 0x8C08013E, // 0000 GETMET R2 R0 K62 0x7C080200, // 0001 CALL R2 1 0x88080101, // 0002 GETMBR R2 R0 K1 - 0x8C080540, // 0003 GETMET R2 R2 K64 + 0x8C08053F, // 0003 GETMET R2 R2 K63 0x60100009, // 0004 GETGBL R4 G9 0x5C140200, // 0005 MOVE R5 R1 0x7C100200, // 0006 CALL R4 1 @@ -2674,7 +2681,7 @@ be_local_closure(class_lvh_obj_init, /* name */ 0x60180003, // 0000 GETGBL R6 G3 0x5C1C0000, // 0001 MOVE R7 R0 0x7C180200, // 0002 CALL R6 1 - 0x8C180D41, // 0003 GETMET R6 R6 K65 + 0x8C180D40, // 0003 GETMET R6 R6 K64 0x5C200200, // 0004 MOVE R8 R1 0x5C240400, // 0005 MOVE R9 R2 0x5C280600, // 0006 MOVE R10 R3 @@ -2708,7 +2715,7 @@ be_local_closure(class_lvh_obj_get_toggle, /* name */ 0x88040103, // 0000 GETMBR R1 R0 K3 0x8C04030B, // 0001 GETMET R1 R1 K11 0xB80E0A00, // 0002 GETNGBL R3 K5 - 0x880C0742, // 0003 GETMBR R3 R3 K66 + 0x880C0741, // 0003 GETMBR R3 R3 K65 0x7C040400, // 0004 CALL R1 2 0x80040200, // 0005 RET 1 R1 }) @@ -2734,14 +2741,14 @@ be_local_closure(class_lvh_obj_set_text_font, /* name */ be_str_weak(set_text_font), &be_const_str_solidified, ( &(const binstruction[12]) { /* code */ - 0x8C080143, // 0000 GETMET R2 R0 K67 + 0x8C080142, // 0000 GETMET R2 R0 K66 0x5C100200, // 0001 MOVE R4 R1 0x7C080400, // 0002 CALL R2 2 0x4C0C0000, // 0003 LDNIL R3 0x200C0403, // 0004 NE R3 R2 R3 0x780E0004, // 0005 JMPF R3 #000B 0x880C0103, // 0006 GETMBR R3 R0 K3 - 0x8C0C0744, // 0007 GETMET R3 R3 K68 + 0x8C0C0743, // 0007 GETMET R3 R3 K67 0x5C140400, // 0008 MOVE R5 R2 0x58180018, // 0009 LDCONST R6 K24 0x7C0C0600, // 000A CALL R3 3 @@ -2769,7 +2776,7 @@ be_local_closure(class_lvh_obj_get_click, /* name */ be_str_weak(get_click), &be_const_str_solidified, ( &(const binstruction[ 3]) { /* code */ - 0x8C040145, // 0000 GETMET R1 R0 K69 + 0x8C040144, // 0000 GETMET R1 R0 K68 0x7C040200, // 0001 CALL R1 1 0x80040200, // 0002 RET 1 R1 }) @@ -2800,7 +2807,7 @@ be_local_closure(class_lvh_obj_set_pad_right2, /* name */ 0x20080403, // 0002 NE R2 R2 R3 0x780A0009, // 0003 JMPF R2 #000E 0x88080103, // 0004 GETMBR R2 R0 K3 - 0x8C080546, // 0005 GETMET R2 R2 K70 + 0x8C080545, // 0005 GETMET R2 R2 K69 0x60100009, // 0006 GETGBL R4 G9 0x5C140200, // 0007 MOVE R5 R1 0x7C100200, // 0008 CALL R4 1 @@ -2837,7 +2844,7 @@ be_local_closure(class_lvh_obj_get_action, /* name */ 0x78060001, // 0001 JMPF R1 #0004 0x5C080200, // 0002 MOVE R2 R1 0x70020000, // 0003 JMP #0005 - 0x58080047, // 0004 LDCONST R2 K71 + 0x58080046, // 0004 LDCONST R2 K70 0x80040400, // 0005 RET 1 R2 }) ) @@ -2862,41 +2869,41 @@ be_local_closure(class_lvh_obj_setmember, /* name */ be_str_weak(setmember), &be_const_str_solidified, ( &(const binstruction[164]) { /* code */ - 0xA40E5A00, // 0000 IMPORT R3 K45 + 0xA40E5800, // 0000 IMPORT R3 K44 0xA4121C00, // 0001 IMPORT R4 K14 - 0x8C14072E, // 0002 GETMET R5 R3 K46 + 0x8C14072D, // 0002 GETMET R5 R3 K45 0x5C1C0200, // 0003 MOVE R7 R1 - 0x5820002F, // 0004 LDCONST R8 K47 + 0x5820002E, // 0004 LDCONST R8 K46 0x7C140600, // 0005 CALL R5 3 0x74160004, // 0006 JMPT R5 #000C - 0x8C14072E, // 0007 GETMET R5 R3 K46 + 0x8C14072D, // 0007 GETMET R5 R3 K45 0x5C1C0200, // 0008 MOVE R7 R1 - 0x58200030, // 0009 LDCONST R8 K48 + 0x5820002F, // 0009 LDCONST R8 K47 0x7C140600, // 000A CALL R5 3 0x78160000, // 000B JMPF R5 #000D 0x80000A00, // 000C RET 0 0x60140004, // 000D GETGBL R5 G4 0x5C180400, // 000E MOVE R6 R2 0x7C140200, // 000F CALL R5 1 - 0x1C140B48, // 0010 EQ R5 R5 K72 + 0x1C140B47, // 0010 EQ R5 R5 K71 0x78160006, // 0011 JMPF R5 #0019 - 0xA4169200, // 0012 IMPORT R5 K73 + 0xA4169000, // 0012 IMPORT R5 K72 0x60180009, // 0013 GETGBL R6 G9 - 0x8C1C0B4A, // 0014 GETMET R7 R5 K74 + 0x8C1C0B49, // 0014 GETMET R7 R5 K73 0x5C240400, // 0015 MOVE R9 R2 0x7C1C0400, // 0016 CALL R7 2 0x7C180200, // 0017 CALL R6 1 0x5C080C00, // 0018 MOVE R2 R6 - 0x8C14074B, // 0019 GETMET R5 R3 K75 + 0x8C14074A, // 0019 GETMET R5 R3 K74 0x5C1C0200, // 001A MOVE R7 R1 - 0x5820004C, // 001B LDCONST R8 K76 + 0x5820004B, // 001B LDCONST R8 K75 0x7C140600, // 001C CALL R5 3 0x78160009, // 001D JMPF R5 #0028 0x5415FFFD, // 001E LDINT R5 -2 0x40163005, // 001F CONNECT R5 K24 R5 0x94040205, // 0020 GETIDX R1 R1 R5 0xB8160A00, // 0021 GETNGBL R5 K5 - 0x8C140B4D, // 0022 GETMET R5 R5 K77 + 0x8C140B4C, // 0022 GETMET R5 R5 K76 0x601C0009, // 0023 GETGBL R7 G9 0x5C200400, // 0024 MOVE R8 R2 0x7C1C0200, // 0025 CALL R7 1 @@ -2906,13 +2913,13 @@ be_local_closure(class_lvh_obj_setmember, /* name */ 0x6018000C, // 0029 GETGBL R6 G12 0x5C1C0200, // 002A MOVE R7 R1 0x7C180200, // 002B CALL R6 1 - 0x28180D31, // 002C GE R6 R6 K49 + 0x28180D30, // 002C GE R6 R6 K48 0x781A001F, // 002D JMPF R6 #004E - 0x8C180732, // 002E GETMET R6 R3 K50 + 0x8C180731, // 002E GETMET R6 R3 K49 0x5421FFFE, // 002F LDINT R8 -1 0x94200208, // 0030 GETIDX R8 R1 R8 0x7C180400, // 0031 CALL R6 2 - 0x8C1C0732, // 0032 GETMET R7 R3 K50 + 0x8C1C0731, // 0032 GETMET R7 R3 K49 0x5425FFFD, // 0033 LDINT R9 -2 0x94240209, // 0034 GETIDX R9 R1 R9 0x7C1C0400, // 0035 CALL R7 2 @@ -2930,32 +2937,32 @@ be_local_closure(class_lvh_obj_setmember, /* name */ 0x7822000B, // 0041 JMPF R8 #004E 0x60200009, // 0042 GETGBL R8 G9 0x5425FFFD, // 0043 LDINT R9 -2 - 0x40241333, // 0044 CONNECT R9 R9 K51 + 0x40241332, // 0044 CONNECT R9 R9 K50 0x94240209, // 0045 GETIDX R9 R1 R9 0x7C200200, // 0046 CALL R8 1 0x5425FFFC, // 0047 LDINT R9 -3 0x40263009, // 0048 CONNECT R9 K24 R9 0x94040209, // 0049 GETIDX R1 R1 R9 - 0x8C240134, // 004A GETMET R9 R0 K52 + 0x8C240133, // 004A GETMET R9 R0 K51 0x5C2C1000, // 004B MOVE R11 R8 0x7C240400, // 004C CALL R9 2 0x5C141200, // 004D MOVE R5 R9 - 0x88180135, // 004E GETMBR R6 R0 K53 - 0x8C180D36, // 004F GETMET R6 R6 K54 + 0x88180134, // 004E GETMBR R6 R0 K52 + 0x8C180D35, // 004F GETMET R6 R6 K53 0x5C200200, // 0050 MOVE R8 R1 0x7C180400, // 0051 CALL R6 2 0x4C1C0000, // 0052 LDNIL R7 0x20180C07, // 0053 NE R6 R6 R7 0x781A0000, // 0054 JMPF R6 #0056 0x80000C00, // 0055 RET 0 - 0x8C180937, // 0056 GETMET R6 R4 K55 + 0x8C180936, // 0056 GETMET R6 R4 K54 0x5C200000, // 0057 MOVE R8 R0 - 0x00265E01, // 0058 ADD R9 K47 R1 + 0x00265C01, // 0058 ADD R9 K46 R1 0x7C180600, // 0059 CALL R6 3 0x601C0004, // 005A GETGBL R7 G4 0x5C200C00, // 005B MOVE R8 R6 0x7C1C0200, // 005C CALL R7 1 - 0x1C1C0F38, // 005D EQ R7 R7 K56 + 0x1C1C0F37, // 005D EQ R7 R7 K55 0x781E000A, // 005E JMPF R7 #006A 0x5C1C0C00, // 005F MOVE R7 R6 0x5C200000, // 0060 MOVE R8 R0 @@ -2968,13 +2975,13 @@ be_local_closure(class_lvh_obj_setmember, /* name */ 0x58280018, // 0067 LDCONST R10 K24 0x7C1C0600, // 0068 CALL R7 3 0x80000E00, // 0069 RET 0 - 0x881C0139, // 006A GETMBR R7 R0 K57 - 0x8C1C0F36, // 006B GETMET R7 R7 K54 + 0x881C0138, // 006A GETMBR R7 R0 K56 + 0x8C1C0F35, // 006B GETMET R7 R7 K53 0x5C240200, // 006C MOVE R9 R1 0x5C280200, // 006D MOVE R10 R1 0x7C1C0600, // 006E CALL R7 3 0x5C040E00, // 006F MOVE R1 R7 - 0x8C1C014E, // 0070 GETMET R7 R0 K78 + 0x8C1C014D, // 0070 GETMET R7 R0 K77 0x5C240200, // 0071 MOVE R9 R1 0x7C1C0400, // 0072 CALL R7 2 0x781E0003, // 0073 JMPF R7 #0078 @@ -2985,30 +2992,30 @@ be_local_closure(class_lvh_obj_setmember, /* name */ 0x4C1C0000, // 0078 LDNIL R7 0x1C1C0A07, // 0079 EQ R7 R5 R7 0x781E000E, // 007A JMPF R7 #008A - 0x8C1C0937, // 007B GETMET R7 R4 K55 + 0x8C1C0936, // 007B GETMET R7 R4 K54 0x88240103, // 007C GETMBR R9 R0 K3 - 0x002A5E01, // 007D ADD R10 K47 R1 + 0x002A5C01, // 007D ADD R10 K46 R1 0x7C1C0600, // 007E CALL R7 3 0x5C180E00, // 007F MOVE R6 R7 0x601C0004, // 0080 GETGBL R7 G4 0x5C200C00, // 0081 MOVE R8 R6 0x7C1C0200, // 0082 CALL R7 1 - 0x1C1C0F38, // 0083 EQ R7 R7 K56 + 0x1C1C0F37, // 0083 EQ R7 R7 K55 0x781E0004, // 0084 JMPF R7 #008A 0x5C1C0C00, // 0085 MOVE R7 R6 0x88200103, // 0086 GETMBR R8 R0 K3 0x5C240400, // 0087 MOVE R9 R2 0x7C1C0400, // 0088 CALL R7 2 0x80040E00, // 0089 RET 1 R7 - 0x8C1C0937, // 008A GETMET R7 R4 K55 + 0x8C1C0936, // 008A GETMET R7 R4 K54 0x88240103, // 008B GETMBR R9 R0 K3 - 0x002A9E01, // 008C ADD R10 K79 R1 + 0x002A9C01, // 008C ADD R10 K78 R1 0x7C1C0600, // 008D CALL R7 3 0x5C180E00, // 008E MOVE R6 R7 0x601C0004, // 008F GETGBL R7 G4 0x5C200C00, // 0090 MOVE R8 R6 0x7C1C0200, // 0091 CALL R7 1 - 0x1C1C0F38, // 0092 EQ R7 R7 K56 + 0x1C1C0F37, // 0092 EQ R7 R7 K55 0x781E000A, // 0093 JMPF R7 #009F 0x5C1C0C00, // 0094 MOVE R7 R6 0x88200103, // 0095 GETMBR R8 R0 K3 @@ -3022,7 +3029,7 @@ be_local_closure(class_lvh_obj_setmember, /* name */ 0x7C1C0600, // 009D CALL R7 3 0x80040E00, // 009E RET 1 R7 0x601C0001, // 009F GETGBL R7 G1 - 0x58200050, // 00A0 LDCONST R8 K80 + 0x5820004F, // 00A0 LDCONST R8 K79 0x5C240200, // 00A1 MOVE R9 R1 0x7C1C0400, // 00A2 CALL R7 2 0x80000000, // 00A3 RET 0 @@ -3049,7 +3056,7 @@ be_local_closure(class_lvh_obj_set_value_font, /* name */ be_str_weak(set_value_font), &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C080151, // 0000 GETMET R2 R0 K81 + 0x8C080150, // 0000 GETMET R2 R0 K80 0x5C100200, // 0001 MOVE R4 R1 0x7C080400, // 0002 CALL R2 2 0x80000000, // 0003 RET 0 @@ -3100,36 +3107,36 @@ be_local_closure(class_lvh_obj_set_toggle, /* name */ be_str_weak(set_toggle), &be_const_str_solidified, ( &(const binstruction[32]) { /* code */ - 0xA40A5A00, // 0000 IMPORT R2 K45 + 0xA40A5800, // 0000 IMPORT R2 K44 0x600C0004, // 0001 GETGBL R3 G4 0x5C100200, // 0002 MOVE R4 R1 0x7C0C0200, // 0003 CALL R3 1 - 0x1C0C072D, // 0004 EQ R3 R3 K45 + 0x1C0C072C, // 0004 EQ R3 R3 K44 0x780E000C, // 0005 JMPF R3 #0013 - 0x8C0C0552, // 0006 GETMET R3 R2 K82 + 0x8C0C0551, // 0006 GETMET R3 R2 K81 0x60140008, // 0007 GETGBL R5 G8 0x5C180200, // 0008 MOVE R6 R1 0x7C140200, // 0009 CALL R5 1 0x7C0C0400, // 000A CALL R3 2 0x5C040600, // 000B MOVE R1 R3 - 0x1C0C0353, // 000C EQ R3 R1 K83 + 0x1C0C0352, // 000C EQ R3 R1 K82 0x780E0001, // 000D JMPF R3 #0010 0x50040200, // 000E LDBOOL R1 1 0 0x70020002, // 000F JMP #0013 - 0x1C0C0354, // 0010 EQ R3 R1 K84 + 0x1C0C0353, // 0010 EQ R3 R1 K83 0x780E0000, // 0011 JMPF R3 #0013 0x50040000, // 0012 LDBOOL R1 0 0 0x78060005, // 0013 JMPF R1 #001A 0x880C0103, // 0014 GETMBR R3 R0 K3 - 0x8C0C073E, // 0015 GETMET R3 R3 K62 + 0x8C0C073D, // 0015 GETMET R3 R3 K61 0xB8160A00, // 0016 GETNGBL R5 K5 - 0x88140B42, // 0017 GETMBR R5 R5 K66 + 0x88140B41, // 0017 GETMBR R5 R5 K65 0x7C0C0400, // 0018 CALL R3 2 0x70020004, // 0019 JMP #001F 0x880C0103, // 001A GETMBR R3 R0 K3 - 0x8C0C073D, // 001B GETMET R3 R3 K61 + 0x8C0C073C, // 001B GETMET R3 R3 K60 0xB8160A00, // 001C GETNGBL R5 K5 - 0x88140B42, // 001D GETMBR R5 R5 K66 + 0x88140B41, // 001D GETMBR R5 R5 K65 0x7C0C0400, // 001E CALL R3 2 0x80000000, // 001F RET 0 }) @@ -3158,7 +3165,7 @@ be_local_closure(class_lvh_obj_get_adjustable, /* name */ 0x88040103, // 0000 GETMBR R1 R0 K3 0x8C040304, // 0001 GETMET R1 R1 K4 0xB80E0A00, // 0002 GETNGBL R3 K5 - 0x880C0755, // 0003 GETMBR R3 R3 K85 + 0x880C0754, // 0003 GETMBR R3 R3 K84 0x7C040400, // 0004 CALL R1 2 0x80040200, // 0005 RET 1 R1 }) @@ -3194,26 +3201,26 @@ be_local_closure(class_lvh_obj_get_align, /* name */ 0x4C080000, // 0007 LDNIL R2 0x80040400, // 0008 RET 1 R2 0x88080101, // 0009 GETMBR R2 R0 K1 - 0x8C080556, // 000A GETMET R2 R2 K86 + 0x8C080555, // 000A GETMET R2 R2 K85 0x5C100200, // 000B MOVE R4 R1 0x7C080400, // 000C CALL R2 2 0xB80E0A00, // 000D GETNGBL R3 K5 - 0x880C0757, // 000E GETMBR R3 R3 K87 + 0x880C0756, // 000E GETMBR R3 R3 K86 0x1C0C0403, // 000F EQ R3 R2 R3 0x780E0001, // 0010 JMPF R3 #0013 - 0x8006B000, // 0011 RET 1 K88 + 0x8006AE00, // 0011 RET 1 K87 0x7002000C, // 0012 JMP #0020 0xB80E0A00, // 0013 GETNGBL R3 K5 - 0x880C0759, // 0014 GETMBR R3 R3 K89 + 0x880C0758, // 0014 GETMBR R3 R3 K88 0x1C0C0403, // 0015 EQ R3 R2 R3 0x780E0001, // 0016 JMPF R3 #0019 - 0x8006B400, // 0017 RET 1 K90 + 0x8006B200, // 0017 RET 1 K89 0x70020006, // 0018 JMP #0020 0xB80E0A00, // 0019 GETNGBL R3 K5 - 0x880C075B, // 001A GETMBR R3 R3 K91 + 0x880C075A, // 001A GETMBR R3 R3 K90 0x1C0C0403, // 001B EQ R3 R2 R3 0x780E0001, // 001C JMPF R3 #001F - 0x8006B800, // 001D RET 1 K92 + 0x8006B600, // 001D RET 1 K91 0x70020000, // 001E JMP #0020 0x80040400, // 001F RET 1 R2 0x80000000, // 0020 RET 0 @@ -3245,7 +3252,7 @@ be_local_closure(class_lvh_obj_get_pad_top, /* name */ 0x20040202, // 0002 NE R1 R1 R2 0x78060007, // 0003 JMPF R1 #000C 0x88040103, // 0004 GETMBR R1 R0 K3 - 0x8C04035D, // 0005 GETMET R1 R1 K93 + 0x8C04035C, // 0005 GETMET R1 R1 K92 0x880C0107, // 0006 GETMBR R3 R0 K7 0xB8120A00, // 0007 GETNGBL R4 K5 0x88100909, // 0008 GETMBR R4 R4 K9 @@ -3281,7 +3288,7 @@ be_local_closure(class_lvh_obj_set_radius2, /* name */ 0x20080403, // 0002 NE R2 R2 R3 0x780A0009, // 0003 JMPF R2 #000E 0x88080103, // 0004 GETMBR R2 R0 K3 - 0x8C08055E, // 0005 GETMET R2 R2 K94 + 0x8C08055D, // 0005 GETMET R2 R2 K93 0x60100009, // 0006 GETGBL R4 G9 0x5C140200, // 0007 MOVE R5 R1 0x7C100200, // 0008 CALL R4 1 @@ -3369,35 +3376,35 @@ be_local_closure(class_lvh_obj_event_cb, /* name */ ( &(const binstruction[84]) { /* code */ 0x88080115, // 0000 GETMBR R2 R0 K21 0x88080516, // 0001 GETMBR R2 R2 K22 - 0x8C0C035F, // 0002 GETMET R3 R1 K95 + 0x8C0C035E, // 0002 GETMET R3 R1 K94 0x7C0C0200, // 0003 CALL R3 1 - 0x88100160, // 0004 GETMBR R4 R0 K96 - 0x20100947, // 0005 NE R4 R4 K71 + 0x8810015F, // 0004 GETMBR R4 R0 K95 + 0x20100946, // 0005 NE R4 R4 K70 0x78120008, // 0006 JMPF R4 #0010 0xB8120A00, // 0007 GETNGBL R4 K5 - 0x88100961, // 0008 GETMBR R4 R4 K97 + 0x88100960, // 0008 GETMBR R4 R4 K96 0x1C100604, // 0009 EQ R4 R3 R4 0x78120004, // 000A JMPF R4 #0010 - 0xB812C400, // 000B GETNGBL R4 K98 - 0x8C100963, // 000C GETMET R4 R4 K99 + 0xB812C200, // 000B GETNGBL R4 K97 + 0x8C100962, // 000C GETMET R4 R4 K98 0x58180018, // 000D LDCONST R6 K24 0x841C0000, // 000E CLOSURE R7 P0 0x7C100600, // 000F CALL R4 3 - 0x88100164, // 0010 GETMBR R4 R0 K100 - 0x8C100936, // 0011 GETMET R4 R4 K54 + 0x88100163, // 0010 GETMBR R4 R0 K99 + 0x8C100935, // 0011 GETMET R4 R4 K53 0x5C180600, // 0012 MOVE R6 R3 0x7C100400, // 0013 CALL R4 2 0x4C140000, // 0014 LDNIL R5 0x20140805, // 0015 NE R5 R4 R5 0x7816003A, // 0016 JMPF R5 #0052 - 0xA416CA00, // 0017 IMPORT R5 K101 - 0x58180047, // 0018 LDCONST R6 K71 + 0xA416C800, // 0017 IMPORT R5 K100 + 0x58180046, // 0018 LDCONST R6 K70 0xB81E0A00, // 0019 GETNGBL R7 K5 - 0x881C0F66, // 001A GETMBR R7 R7 K102 + 0x881C0F65, // 001A GETMBR R7 R7 K101 0x1C1C0607, // 001B EQ R7 R3 R7 0x781E0026, // 001C JMPF R7 #0044 0xA41E1C00, // 001D IMPORT R7 K14 - 0x8C200F37, // 001E GETMET R8 R7 K55 + 0x8C200F36, // 001E GETMET R8 R7 K54 0x5C280000, // 001F MOVE R10 R0 0x502C0200, // 0020 LDBOOL R11 1 0 0x7C200600, // 0021 CALL R8 3 @@ -3407,16 +3414,16 @@ be_local_closure(class_lvh_obj_event_cb, /* name */ 0x60240004, // 0025 GETGBL R9 G4 0x5C281000, // 0026 MOVE R10 R8 0x7C240200, // 0027 CALL R9 1 - 0x20241367, // 0028 NE R9 R9 K103 + 0x20241366, // 0028 NE R9 R9 K102 0x78260006, // 0029 JMPF R9 #0031 0x60240018, // 002A GETGBL R9 G24 - 0x58280068, // 002B LDCONST R10 K104 - 0x8C2C0B69, // 002C GETMET R11 R5 K105 + 0x58280067, // 002B LDCONST R10 K103 + 0x8C2C0B68, // 002C GETMET R11 R5 K104 0x5C341000, // 002D MOVE R13 R8 0x7C2C0400, // 002E CALL R11 2 0x7C240400, // 002F CALL R9 2 0x5C181200, // 0030 MOVE R6 R9 - 0x8C240F37, // 0031 GETMET R9 R7 K55 + 0x8C240F36, // 0031 GETMET R9 R7 K54 0x5C2C0000, // 0032 MOVE R11 R0 0x50300200, // 0033 LDBOOL R12 1 0 0x7C240600, // 0034 CALL R9 3 @@ -3426,25 +3433,25 @@ be_local_closure(class_lvh_obj_event_cb, /* name */ 0x60280004, // 0038 GETGBL R10 G4 0x5C2C1200, // 0039 MOVE R11 R9 0x7C280200, // 003A CALL R10 1 - 0x20281567, // 003B NE R10 R10 K103 + 0x20281566, // 003B NE R10 R10 K102 0x782A0006, // 003C JMPF R10 #0044 0x60280018, // 003D GETGBL R10 G24 - 0x582C006A, // 003E LDCONST R11 K106 - 0x8C300B69, // 003F GETMET R12 R5 K105 + 0x582C0069, // 003E LDCONST R11 K105 + 0x8C300B68, // 003F GETMET R12 R5 K104 0x5C381200, // 0040 MOVE R14 R9 0x7C300400, // 0041 CALL R12 2 0x7C280400, // 0042 CALL R10 2 0x00180C0A, // 0043 ADD R6 R6 R10 0x601C0018, // 0044 GETGBL R7 G24 - 0x5820006B, // 0045 LDCONST R8 K107 + 0x5820006A, // 0045 LDCONST R8 K106 0x88240115, // 0046 GETMBR R9 R0 K21 - 0x8824136C, // 0047 GETMBR R9 R9 K108 - 0x88280123, // 0048 GETMBR R10 R0 K35 + 0x8824136B, // 0047 GETMBR R9 R9 K107 + 0x8828016C, // 0048 GETMBR R10 R0 K108 0x5C2C0800, // 0049 MOVE R11 R4 0x5C300C00, // 004A MOVE R12 R6 0x7C1C0A00, // 004B CALL R7 5 - 0xB822C400, // 004C GETNGBL R8 K98 - 0x8C201163, // 004D GETMET R8 R8 K99 + 0xB822C200, // 004C GETNGBL R8 K97 + 0x8C201162, // 004D GETMET R8 R8 K98 0x58280018, // 004E LDCONST R10 K24 0x842C0001, // 004F CLOSURE R11 P1 0x7C200600, // 0050 CALL R8 3 @@ -3675,13 +3682,13 @@ be_local_closure(class_lvh_obj_set_adjustable, /* name */ 0x88080103, // 0001 GETMBR R2 R0 K3 0x8C080570, // 0002 GETMET R2 R2 K112 0xB8120A00, // 0003 GETNGBL R4 K5 - 0x88100955, // 0004 GETMBR R4 R4 K85 + 0x88100954, // 0004 GETMBR R4 R4 K84 0x7C080400, // 0005 CALL R2 2 0x70020004, // 0006 JMP #000C 0x88080103, // 0007 GETMBR R2 R0 K3 0x8C080571, // 0008 GETMET R2 R2 K113 0xB8120A00, // 0009 GETNGBL R4 K5 - 0x88100955, // 000A GETMBR R4 R4 K85 + 0x88100954, // 000A GETMBR R4 R4 K84 0x7C080400, // 000B CALL R2 2 0x80000000, // 000C RET 0 }) @@ -3707,7 +3714,7 @@ be_local_closure(class_lvh_obj_set_text, /* name */ be_str_weak(set_text), &be_const_str_solidified, ( &(const binstruction[ 9]) { /* code */ - 0x8C08013F, // 0000 GETMET R2 R0 K63 + 0x8C08013E, // 0000 GETMET R2 R0 K62 0x7C080200, // 0001 CALL R2 1 0x88080101, // 0002 GETMBR R2 R0 K1 0x8C080510, // 0003 GETMET R2 R2 K16 @@ -3739,7 +3746,7 @@ be_local_closure(class_lvh_obj_set_value_ofs_y, /* name */ be_str_weak(set_value_ofs_y), &be_const_str_solidified, ( &(const binstruction[ 9]) { /* code */ - 0x8C08013F, // 0000 GETMET R2 R0 K63 + 0x8C08013E, // 0000 GETMET R2 R0 K62 0x7C080200, // 0001 CALL R2 1 0x88080101, // 0002 GETMBR R2 R0 K1 0x8C080573, // 0003 GETMET R2 R2 K115 @@ -3860,7 +3867,7 @@ be_local_closure(class_lvh_obj_set_label_mode, /* name */ 0x4C0C0000, // 0021 LDNIL R3 0x200C0403, // 0022 NE R3 R2 R3 0x780E0005, // 0023 JMPF R3 #002A - 0x8C0C013F, // 0024 GETMET R3 R0 K63 + 0x8C0C013E, // 0024 GETMET R3 R0 K62 0x7C0C0200, // 0025 CALL R3 1 0x880C0101, // 0026 GETMBR R3 R0 K1 0x8C0C0783, // 0027 GETMET R3 R3 K131 @@ -3930,28 +3937,28 @@ be_local_closure(class_lvh_obj_set_align, /* name */ 0x1C100518, // 0001 EQ R4 R2 K24 0x78120000, // 0002 JMPF R4 #0004 0x58080018, // 0003 LDCONST R2 K24 - 0x8C10013F, // 0004 GETMET R4 R0 K63 + 0x8C10013E, // 0004 GETMET R4 R0 K62 0x7C100200, // 0005 CALL R4 1 0x1C100318, // 0006 EQ R4 R1 K24 0x74120001, // 0007 JMPT R4 #000A - 0x1C100358, // 0008 EQ R4 R1 K88 + 0x1C100357, // 0008 EQ R4 R1 K87 0x78120002, // 0009 JMPF R4 #000D 0xB8120A00, // 000A GETNGBL R4 K5 - 0x880C0957, // 000B GETMBR R3 R4 K87 + 0x880C0956, // 000B GETMBR R3 R4 K86 0x7002000C, // 000C JMP #001A 0x1C10031A, // 000D EQ R4 R1 K26 0x74120001, // 000E JMPT R4 #0011 - 0x1C10035A, // 000F EQ R4 R1 K90 + 0x1C100359, // 000F EQ R4 R1 K89 0x78120002, // 0010 JMPF R4 #0014 0xB8120A00, // 0011 GETNGBL R4 K5 - 0x880C0959, // 0012 GETMBR R3 R4 K89 + 0x880C0958, // 0012 GETMBR R3 R4 K88 0x70020005, // 0013 JMP #001A 0x1C100384, // 0014 EQ R4 R1 K132 0x74120001, // 0015 JMPT R4 #0018 - 0x1C10035C, // 0016 EQ R4 R1 K92 + 0x1C10035B, // 0016 EQ R4 R1 K91 0x78120001, // 0017 JMPF R4 #001A 0xB8120A00, // 0018 GETNGBL R4 K5 - 0x880C095B, // 0019 GETMBR R3 R4 K91 + 0x880C095A, // 0019 GETMBR R3 R4 K90 0x88100101, // 001A GETMBR R4 R0 K1 0x8C100985, // 001B GETMET R4 R4 K133 0x5C180600, // 001C MOVE R6 R3 @@ -8128,50 +8135,51 @@ be_local_class(lvh_scale, })), be_str_weak(lvh_scale) ); -// compact class 'lvh_scale_section' ktab size: 42, total: 57 (saved 120 bytes) -static const bvalue be_ktab_class_lvh_scale_section[42] = { +// compact class 'lvh_scale_section' ktab size: 43, total: 58 (saved 120 bytes) +static const bvalue be_ktab_class_lvh_scale_section[43] = { /* K0 */ be_nested_str_weak(_style), /* K1 */ be_nested_str_weak(del), /* K2 */ be_nested_str_weak(_style10), /* K3 */ be_nested_str_weak(_style30), - /* K4 */ be_nested_str_weak(_lv_obj), - /* K5 */ be_nested_str_weak(_min), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(_max), - /* K8 */ be_nested_str_weak(_parent_lvh), - /* K9 */ be_nested_str_weak(_page), - /* K10 */ be_nested_str_weak(_hm), - /* K11 */ be_nested_str_weak(lvh_scale), - /* K12 */ be_nested_str_weak(add_section), - /* K13 */ be_nested_str_weak(lv), - /* K14 */ be_nested_str_weak(style), - /* K15 */ be_nested_str_weak(set_style), - /* K16 */ be_nested_str_weak(PART_MAIN), - /* K17 */ be_nested_str_weak(PART_INDICATOR), - /* K18 */ be_nested_str_weak(PART_ITEMS), - /* K19 */ be_nested_str_weak(HSP_X3A_X20_X27scale_section_X27_X20should_X20have_X20a_X20parent_X20of_X20type_X20_X27scale_X27), - /* K20 */ be_nested_str_weak(set_range), - /* K21 */ be_nested_str_weak(string), - /* K22 */ be_nested_str_weak(introspect), - /* K23 */ be_nested_str_weak(startswith), - /* K24 */ be_nested_str_weak(set_), - /* K25 */ be_nested_str_weak(get_), - /* K26 */ be_nested_str_weak(endswith), - /* K27 */ be_nested_str_weak(_X25), - /* K28 */ be_nested_str_weak(pct), - /* K29 */ be_const_int(3), - /* K30 */ be_nested_str_weak(byte), - /* K31 */ be_const_int(2147483647), - /* K32 */ be_nested_str_weak(value_error), - /* K33 */ be_nested_str_weak(only_X20modifiers_X20_X2710_X27_X20or_X20_X2730_X27_X20allowed), - /* K34 */ be_nested_str_weak(_attr_ignore), - /* K35 */ be_nested_str_weak(find), - /* K36 */ be_nested_str_weak(get), - /* K37 */ be_nested_str_weak(function), - /* K38 */ be_nested_str_weak(is_color_attribute), - /* K39 */ be_nested_str_weak(parse_color), - /* K40 */ be_nested_str_weak(_X20for_X20), - /* K41 */ be_nested_str_weak(HSP_X3A_X20Could_X20not_X20find_X20function_X20set_), + /* K4 */ be_nested_str_weak(_delete), + /* K5 */ be_nested_str_weak(_lv_obj), + /* K6 */ be_nested_str_weak(_min), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(_max), + /* K9 */ be_nested_str_weak(_parent_lvh), + /* K10 */ be_nested_str_weak(_page), + /* K11 */ be_nested_str_weak(_hm), + /* K12 */ be_nested_str_weak(lvh_scale), + /* K13 */ be_nested_str_weak(add_section), + /* K14 */ be_nested_str_weak(lv), + /* K15 */ be_nested_str_weak(style), + /* K16 */ be_nested_str_weak(set_style), + /* K17 */ be_nested_str_weak(PART_MAIN), + /* K18 */ be_nested_str_weak(PART_INDICATOR), + /* K19 */ be_nested_str_weak(PART_ITEMS), + /* K20 */ be_nested_str_weak(HSP_X3A_X20_X27scale_section_X27_X20should_X20have_X20a_X20parent_X20of_X20type_X20_X27scale_X27), + /* K21 */ be_nested_str_weak(set_range), + /* K22 */ be_nested_str_weak(string), + /* K23 */ be_nested_str_weak(introspect), + /* K24 */ be_nested_str_weak(startswith), + /* K25 */ be_nested_str_weak(set_), + /* K26 */ be_nested_str_weak(get_), + /* K27 */ be_nested_str_weak(endswith), + /* K28 */ be_nested_str_weak(_X25), + /* K29 */ be_nested_str_weak(pct), + /* K30 */ be_const_int(3), + /* K31 */ be_nested_str_weak(byte), + /* K32 */ be_const_int(2147483647), + /* K33 */ be_nested_str_weak(value_error), + /* K34 */ be_nested_str_weak(only_X20modifiers_X20_X2710_X27_X20or_X20_X2730_X27_X20allowed), + /* K35 */ be_nested_str_weak(_attr_ignore), + /* K36 */ be_nested_str_weak(find), + /* K37 */ be_nested_str_weak(get), + /* K38 */ be_nested_str_weak(function), + /* K39 */ be_nested_str_weak(is_color_attribute), + /* K40 */ be_nested_str_weak(parse_color), + /* K41 */ be_nested_str_weak(_X20for_X20), + /* K42 */ be_nested_str_weak(HSP_X3A_X20Could_X20not_X20find_X20function_X20set_), }; @@ -8193,7 +8201,7 @@ be_local_closure(class_lvh_scale_section__delete, /* name */ &be_ktab_class_lvh_scale_section, /* shared constants */ be_str_weak(_delete), &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ + ( &(const binstruction[21]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x8C040301, // 0001 GETMET R1 R1 K1 0x7C040200, // 0002 CALL R1 1 @@ -8209,7 +8217,12 @@ be_local_closure(class_lvh_scale_section__delete, /* name */ 0x7C040200, // 000C CALL R1 1 0x4C040000, // 000D LDNIL R1 0x90020601, // 000E SETMBR R0 K3 R1 - 0x80000000, // 000F RET 0 + 0x60040003, // 000F GETGBL R1 G3 + 0x5C080000, // 0010 MOVE R2 R0 + 0x7C040200, // 0011 CALL R1 1 + 0x8C040304, // 0012 GETMET R1 R1 K4 + 0x7C040200, // 0013 CALL R1 1 + 0x80000000, // 0014 RET 0 }) ) ); @@ -8234,54 +8247,54 @@ be_local_closure(class_lvh_scale_section_post_init, /* name */ &be_const_str_solidified, ( &(const binstruction[51]) { /* code */ 0x4C040000, // 0000 LDNIL R1 - 0x90020801, // 0001 SETMBR R0 K4 R1 - 0x90020B06, // 0002 SETMBR R0 K5 K6 - 0x90020F06, // 0003 SETMBR R0 K7 K6 + 0x90020A01, // 0001 SETMBR R0 K5 R1 + 0x90020D07, // 0002 SETMBR R0 K6 K7 + 0x90021107, // 0003 SETMBR R0 K8 K7 0x6004000F, // 0004 GETGBL R1 G15 - 0x88080108, // 0005 GETMBR R2 R0 K8 - 0x880C0109, // 0006 GETMBR R3 R0 K9 - 0x880C070A, // 0007 GETMBR R3 R3 K10 - 0x880C070B, // 0008 GETMBR R3 R3 K11 + 0x88080109, // 0005 GETMBR R2 R0 K9 + 0x880C010A, // 0006 GETMBR R3 R0 K10 + 0x880C070B, // 0007 GETMBR R3 R3 K11 + 0x880C070C, // 0008 GETMBR R3 R3 K12 0x7C040400, // 0009 CALL R1 2 0x78060023, // 000A JMPF R1 #002F - 0x88040108, // 000B GETMBR R1 R0 K8 - 0x88040304, // 000C GETMBR R1 R1 K4 - 0x8C04030C, // 000D GETMET R1 R1 K12 + 0x88040109, // 000B GETMBR R1 R0 K9 + 0x88040305, // 000C GETMBR R1 R1 K5 + 0x8C04030D, // 000D GETMET R1 R1 K13 0x7C040200, // 000E CALL R1 1 - 0x90020801, // 000F SETMBR R0 K4 R1 - 0xB8061A00, // 0010 GETNGBL R1 K13 - 0x8C04030E, // 0011 GETMET R1 R1 K14 + 0x90020A01, // 000F SETMBR R0 K5 R1 + 0xB8061C00, // 0010 GETNGBL R1 K14 + 0x8C04030F, // 0011 GETMET R1 R1 K15 0x7C040200, // 0012 CALL R1 1 0x90020001, // 0013 SETMBR R0 K0 R1 - 0x88040104, // 0014 GETMBR R1 R0 K4 - 0x8C04030F, // 0015 GETMET R1 R1 K15 - 0xB80E1A00, // 0016 GETNGBL R3 K13 - 0x880C0710, // 0017 GETMBR R3 R3 K16 + 0x88040105, // 0014 GETMBR R1 R0 K5 + 0x8C040310, // 0015 GETMET R1 R1 K16 + 0xB80E1C00, // 0016 GETNGBL R3 K14 + 0x880C0711, // 0017 GETMBR R3 R3 K17 0x88100100, // 0018 GETMBR R4 R0 K0 0x7C040600, // 0019 CALL R1 3 - 0xB8061A00, // 001A GETNGBL R1 K13 - 0x8C04030E, // 001B GETMET R1 R1 K14 + 0xB8061C00, // 001A GETNGBL R1 K14 + 0x8C04030F, // 001B GETMET R1 R1 K15 0x7C040200, // 001C CALL R1 1 0x90020401, // 001D SETMBR R0 K2 R1 - 0x88040104, // 001E GETMBR R1 R0 K4 - 0x8C04030F, // 001F GETMET R1 R1 K15 - 0xB80E1A00, // 0020 GETNGBL R3 K13 - 0x880C0711, // 0021 GETMBR R3 R3 K17 + 0x88040105, // 001E GETMBR R1 R0 K5 + 0x8C040310, // 001F GETMET R1 R1 K16 + 0xB80E1C00, // 0020 GETNGBL R3 K14 + 0x880C0712, // 0021 GETMBR R3 R3 K18 0x88100102, // 0022 GETMBR R4 R0 K2 0x7C040600, // 0023 CALL R1 3 - 0xB8061A00, // 0024 GETNGBL R1 K13 - 0x8C04030E, // 0025 GETMET R1 R1 K14 + 0xB8061C00, // 0024 GETNGBL R1 K14 + 0x8C04030F, // 0025 GETMET R1 R1 K15 0x7C040200, // 0026 CALL R1 1 0x90020601, // 0027 SETMBR R0 K3 R1 - 0x88040104, // 0028 GETMBR R1 R0 K4 - 0x8C04030F, // 0029 GETMET R1 R1 K15 - 0xB80E1A00, // 002A GETNGBL R3 K13 - 0x880C0712, // 002B GETMBR R3 R3 K18 + 0x88040105, // 0028 GETMBR R1 R0 K5 + 0x8C040310, // 0029 GETMET R1 R1 K16 + 0xB80E1C00, // 002A GETNGBL R3 K14 + 0x880C0713, // 002B GETMBR R3 R3 K19 0x88100103, // 002C GETMBR R4 R0 K3 0x7C040600, // 002D CALL R1 3 0x70020002, // 002E JMP #0032 0x60040001, // 002F GETGBL R1 G1 - 0x58080013, // 0030 LDCONST R2 K19 + 0x58080014, // 0030 LDCONST R2 K20 0x7C040200, // 0031 CALL R1 1 0x80000000, // 0032 RET 0 }) @@ -8310,11 +8323,11 @@ be_local_closure(class_lvh_scale_section_set_min, /* name */ 0x60080009, // 0000 GETGBL R2 G9 0x5C0C0200, // 0001 MOVE R3 R1 0x7C080200, // 0002 CALL R2 1 - 0x880C0107, // 0003 GETMBR R3 R0 K7 + 0x880C0108, // 0003 GETMBR R3 R0 K8 0x14100602, // 0004 LT R4 R3 R2 0x78120000, // 0005 JMPF R4 #0007 0x5C0C0400, // 0006 MOVE R3 R2 - 0x8C100114, // 0007 GETMET R4 R0 K20 + 0x8C100115, // 0007 GETMET R4 R0 K21 0x5C180400, // 0008 MOVE R6 R2 0x5C1C0600, // 0009 MOVE R7 R3 0x7C100600, // 000A CALL R4 3 @@ -8342,10 +8355,10 @@ be_local_closure(class_lvh_scale_section_set_range, /* name */ be_str_weak(set_range), &be_const_str_solidified, ( &(const binstruction[ 8]) { /* code */ - 0x90020A01, // 0000 SETMBR R0 K5 R1 - 0x90020E02, // 0001 SETMBR R0 K7 R2 - 0x880C0104, // 0002 GETMBR R3 R0 K4 - 0x8C0C0714, // 0003 GETMET R3 R3 K20 + 0x90020C01, // 0000 SETMBR R0 K6 R1 + 0x90021002, // 0001 SETMBR R0 K8 R2 + 0x880C0105, // 0002 GETMBR R3 R0 K5 + 0x8C0C0715, // 0003 GETMET R3 R3 K21 0x5C140200, // 0004 MOVE R5 R1 0x5C180400, // 0005 MOVE R6 R2 0x7C0C0600, // 0006 CALL R3 3 @@ -8373,14 +8386,14 @@ be_local_closure(class_lvh_scale_section_set_max, /* name */ be_str_weak(set_max), &be_const_str_solidified, ( &(const binstruction[12]) { /* code */ - 0x88080105, // 0000 GETMBR R2 R0 K5 + 0x88080106, // 0000 GETMBR R2 R0 K6 0x600C0009, // 0001 GETGBL R3 G9 0x5C100200, // 0002 MOVE R4 R1 0x7C0C0200, // 0003 CALL R3 1 0x24100403, // 0004 GT R4 R2 R3 0x78120000, // 0005 JMPF R4 #0007 0x5C080600, // 0006 MOVE R2 R3 - 0x8C100114, // 0007 GETMET R4 R0 K20 + 0x8C100115, // 0007 GETMET R4 R0 K21 0x5C180400, // 0008 MOVE R6 R2 0x5C1C0600, // 0009 MOVE R7 R3 0x7C100600, // 000A CALL R4 3 @@ -8408,29 +8421,29 @@ be_local_closure(class_lvh_scale_section_setmember, /* name */ be_str_weak(setmember), &be_const_str_solidified, ( &(const binstruction[141]) { /* code */ - 0xA40E2A00, // 0000 IMPORT R3 K21 - 0xA4122C00, // 0001 IMPORT R4 K22 - 0x8C140717, // 0002 GETMET R5 R3 K23 + 0xA40E2C00, // 0000 IMPORT R3 K22 + 0xA4122E00, // 0001 IMPORT R4 K23 + 0x8C140718, // 0002 GETMET R5 R3 K24 0x5C1C0200, // 0003 MOVE R7 R1 - 0x58200018, // 0004 LDCONST R8 K24 + 0x58200019, // 0004 LDCONST R8 K25 0x7C140600, // 0005 CALL R5 3 0x74160004, // 0006 JMPT R5 #000C - 0x8C140717, // 0007 GETMET R5 R3 K23 + 0x8C140718, // 0007 GETMET R5 R3 K24 0x5C1C0200, // 0008 MOVE R7 R1 - 0x58200019, // 0009 LDCONST R8 K25 + 0x5820001A, // 0009 LDCONST R8 K26 0x7C140600, // 000A CALL R5 3 0x78160000, // 000B JMPF R5 #000D 0x80000A00, // 000C RET 0 - 0x8C14071A, // 000D GETMET R5 R3 K26 + 0x8C14071B, // 000D GETMET R5 R3 K27 0x5C1C0200, // 000E MOVE R7 R1 - 0x5820001B, // 000F LDCONST R8 K27 + 0x5820001C, // 000F LDCONST R8 K28 0x7C140600, // 0010 CALL R5 3 0x78160009, // 0011 JMPF R5 #001C 0x5415FFFD, // 0012 LDINT R5 -2 - 0x40160C05, // 0013 CONNECT R5 K6 R5 + 0x40160E05, // 0013 CONNECT R5 K7 R5 0x94040205, // 0014 GETIDX R1 R1 R5 - 0xB8161A00, // 0015 GETNGBL R5 K13 - 0x8C140B1C, // 0016 GETMET R5 R5 K28 + 0xB8161C00, // 0015 GETNGBL R5 K14 + 0x8C140B1D, // 0016 GETMET R5 R5 K29 0x601C0009, // 0017 GETGBL R7 G9 0x5C200400, // 0018 MOVE R8 R2 0x7C1C0200, // 0019 CALL R7 1 @@ -8440,13 +8453,13 @@ be_local_closure(class_lvh_scale_section_setmember, /* name */ 0x6018000C, // 001D GETGBL R6 G12 0x5C1C0200, // 001E MOVE R7 R1 0x7C180200, // 001F CALL R6 1 - 0x28180D1D, // 0020 GE R6 R6 K29 + 0x28180D1E, // 0020 GE R6 R6 K30 0x781A0023, // 0021 JMPF R6 #0046 - 0x8C18071E, // 0022 GETMET R6 R3 K30 + 0x8C18071F, // 0022 GETMET R6 R3 K31 0x5421FFFE, // 0023 LDINT R8 -1 0x94200208, // 0024 GETIDX R8 R1 R8 0x7C180400, // 0025 CALL R6 2 - 0x8C1C071E, // 0026 GETMET R7 R3 K30 + 0x8C1C071F, // 0026 GETMET R7 R3 K31 0x5425FFFD, // 0027 LDINT R9 -2 0x94240209, // 0028 GETIDX R9 R1 R9 0x7C1C0400, // 0029 CALL R7 2 @@ -8464,12 +8477,12 @@ be_local_closure(class_lvh_scale_section_setmember, /* name */ 0x7822000F, // 0035 JMPF R8 #0046 0x60200009, // 0036 GETGBL R8 G9 0x5425FFFD, // 0037 LDINT R9 -2 - 0x4024131F, // 0038 CONNECT R9 R9 K31 + 0x40241320, // 0038 CONNECT R9 R9 K32 0x94240209, // 0039 GETIDX R9 R1 R9 0x7C200200, // 003A CALL R8 1 0x5C141000, // 003B MOVE R5 R8 0x5421FFFC, // 003C LDINT R8 -3 - 0x40220C08, // 003D CONNECT R8 K6 R8 + 0x40220E08, // 003D CONNECT R8 K7 R8 0x94040208, // 003E GETIDX R1 R1 R8 0x54220009, // 003F LDINT R8 10 0x20200A08, // 0040 NE R8 R5 R8 @@ -8477,9 +8490,9 @@ be_local_closure(class_lvh_scale_section_setmember, /* name */ 0x5422001D, // 0042 LDINT R8 30 0x20200A08, // 0043 NE R8 R5 R8 0x78220000, // 0044 JMPF R8 #0046 - 0xB0064121, // 0045 RAISE 1 K32 K33 - 0x88180122, // 0046 GETMBR R6 R0 K34 - 0x8C180D23, // 0047 GETMET R6 R6 K35 + 0xB0064322, // 0045 RAISE 1 K33 K34 + 0x88180123, // 0046 GETMBR R6 R0 K35 + 0x8C180D24, // 0047 GETMET R6 R6 K36 0x5C200200, // 0048 MOVE R8 R1 0x7C180400, // 0049 CALL R6 2 0x4C1C0000, // 004A LDNIL R7 @@ -8496,35 +8509,35 @@ be_local_closure(class_lvh_scale_section_setmember, /* name */ 0x1C1C0A07, // 0055 EQ R7 R5 R7 0x781E0000, // 0056 JMPF R7 #0058 0x88180103, // 0057 GETMBR R6 R0 K3 - 0x8C1C0924, // 0058 GETMET R7 R4 K36 + 0x8C1C0925, // 0058 GETMET R7 R4 K37 0x5C240000, // 0059 MOVE R9 R0 - 0x002A3001, // 005A ADD R10 K24 R1 + 0x002A3201, // 005A ADD R10 K25 R1 0x7C1C0600, // 005B CALL R7 3 0x60200004, // 005C GETGBL R8 G4 0x5C240E00, // 005D MOVE R9 R7 0x7C200200, // 005E CALL R8 1 - 0x1C201125, // 005F EQ R8 R8 K37 + 0x1C201126, // 005F EQ R8 R8 K38 0x78220004, // 0060 JMPF R8 #0066 0x5C200E00, // 0061 MOVE R8 R7 0x5C240000, // 0062 MOVE R9 R0 0x5C280400, // 0063 MOVE R10 R2 0x7C200400, // 0064 CALL R8 2 0x80001000, // 0065 RET 0 - 0x8C200924, // 0066 GETMET R8 R4 K36 + 0x8C200925, // 0066 GETMET R8 R4 K37 0x5C280C00, // 0067 MOVE R10 R6 - 0x002E3001, // 0068 ADD R11 K24 R1 + 0x002E3201, // 0068 ADD R11 K25 R1 0x7C200600, // 0069 CALL R8 3 0x5C1C1000, // 006A MOVE R7 R8 0x60200004, // 006B GETGBL R8 G4 0x5C240E00, // 006C MOVE R9 R7 0x7C200200, // 006D CALL R8 1 - 0x1C201125, // 006E EQ R8 R8 K37 + 0x1C201126, // 006E EQ R8 R8 K38 0x78220018, // 006F JMPF R8 #0089 - 0x8C200126, // 0070 GETMET R8 R0 K38 + 0x8C200127, // 0070 GETMET R8 R0 K39 0x5C280200, // 0071 MOVE R10 R1 0x7C200400, // 0072 CALL R8 2 0x78220003, // 0073 JMPF R8 #0078 - 0x8C200127, // 0074 GETMET R8 R0 K39 + 0x8C200128, // 0074 GETMET R8 R0 K40 0x5C280400, // 0075 MOVE R10 R2 0x7C200400, // 0076 CALL R8 2 0x5C081000, // 0077 MOVE R2 R8 @@ -8537,7 +8550,7 @@ be_local_closure(class_lvh_scale_section_setmember, /* name */ 0x70020006, // 007E JMP #0086 0xAC200002, // 007F CATCH R8 0 2 0x70020003, // 0080 JMP #0085 - 0x00281328, // 0081 ADD R10 R9 K40 + 0x00281329, // 0081 ADD R10 R9 K41 0x00281401, // 0082 ADD R10 R10 R1 0xB004100A, // 0083 RAISE 1 R8 R10 0x70020000, // 0084 JMP #0086 @@ -8546,7 +8559,7 @@ be_local_closure(class_lvh_scale_section_setmember, /* name */ 0x80041000, // 0087 RET 1 R8 0x70020002, // 0088 JMP #008C 0x60200001, // 0089 GETGBL R8 G1 - 0x00265201, // 008A ADD R9 K41 R1 + 0x00265401, // 008A ADD R9 K42 R1 0x7C200200, // 008B CALL R8 1 0x80000000, // 008C RET 0 }) @@ -10206,55 +10219,225 @@ be_local_class(lvh_scr, })), be_str_weak(lvh_scr) ); -// compact class 'lvh_page' ktab size: 38, total: 62 (saved 192 bytes) -static const bvalue be_ktab_class_lvh_page[38] = { - /* K0 */ be_nested_str_weak(_page_id), - /* K1 */ be_nested_str_weak(_obj_id), - /* K2 */ be_nested_str_weak(find), - /* K3 */ be_nested_str_weak(remove), - /* K4 */ be_nested_str_weak(p_X25ib_X25i), - /* K5 */ be_nested_str_weak(_page), - /* K6 */ be_nested_str_weak(id), - /* K7 */ be_nested_str_weak(global), - /* K8 */ be_nested_str_weak(_hm), - /* K9 */ be_const_int(1), - /* K10 */ be_const_int(0), - /* K11 */ be_nested_str_weak(_lv_scr), - /* K12 */ be_nested_str_weak(lv), - /* K13 */ be_nested_str_weak(layer_top), - /* K14 */ be_nested_str_weak(obj), - /* K15 */ be_nested_str_weak(scr_act), - /* K16 */ be_nested_str_weak(get_style_bg_color), - /* K17 */ be_nested_str_weak(set_style_bg_color), - /* K18 */ be_nested_str_weak(lvh_scr), - /* K19 */ be_nested_str_weak(p), - /* K20 */ be_nested_str_weak(b0), - /* K21 */ be_nested_str_weak(keys), - /* K22 */ be_nested_str_weak(push), - /* K23 */ be_nested_str_weak(stop_iteration), - /* K24 */ be_nested_str_weak(contains), - /* K25 */ be_nested_str_weak(delete), - /* K26 */ be_nested_str_weak(_remove_page), - /* K27 */ be_nested_str_weak(_p), - /* K28 */ be_nested_str_weak(page_dir_to), - /* K29 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25i_X22_X3A_X22out_X22_X7D_X7D), - /* K30 */ be_nested_str_weak(lvh_page_cur_idx), - /* K31 */ be_nested_str_weak(tasmota), - /* K32 */ be_nested_str_weak(set_timer), - /* K33 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25i_X22_X3A_X22in_X22_X7D_X7D), - /* K34 */ be_nested_str_weak(screen_load), - /* K35 */ be_nested_str_weak(show_anim), - /* K36 */ be_nested_str_weak(SCR_LOAD_ANIM_NONE), - /* K37 */ be_nested_str_weak(screen_load_anim), +// compact class 'lvh_page' ktab size: 47, total: 73 (saved 208 bytes) +static const bvalue be_ktab_class_lvh_page[47] = { + /* K0 */ be_nested_str_weak(_clear), + /* K1 */ be_nested_str_weak(string), + /* K2 */ be_nested_str_weak(introspect), + /* K3 */ be_nested_str_weak(startswith), + /* K4 */ be_nested_str_weak(set_), + /* K5 */ be_nested_str_weak(get_), + /* K6 */ be_nested_str_weak(get), + /* K7 */ be_nested_str_weak(function), + /* K8 */ be_nested_str_weak(undefined), + /* K9 */ be_nested_str_weak(_obj_id), + /* K10 */ be_nested_str_weak(keys), + /* K11 */ be_nested_str_weak(push), + /* K12 */ be_nested_str_weak(stop_iteration), + /* K13 */ be_const_int(0), + /* K14 */ be_nested_str_weak(contains), + /* K15 */ be_nested_str_weak(_delete), + /* K16 */ be_const_int(1), + /* K17 */ be_nested_str_weak(_lv_scr), + /* K18 */ be_nested_str_weak(find), + /* K19 */ be_nested_str_weak(remove), + /* K20 */ be_nested_str_weak(p_X25ib_X25i), + /* K21 */ be_nested_str_weak(_page), + /* K22 */ be_nested_str_weak(id), + /* K23 */ be_nested_str_weak(global), + /* K24 */ be_nested_str_weak(_hm), + /* K25 */ be_nested_str_weak(_page_id), + /* K26 */ be_nested_str_weak(lv), + /* K27 */ be_nested_str_weak(layer_top), + /* K28 */ be_nested_str_weak(obj), + /* K29 */ be_nested_str_weak(scr_act), + /* K30 */ be_nested_str_weak(get_style_bg_color), + /* K31 */ be_nested_str_weak(set_style_bg_color), + /* K32 */ be_nested_str_weak(lvh_scr), + /* K33 */ be_nested_str_weak(p_X25s), + /* K34 */ be_nested_str_weak(p_X25sb0), + /* K35 */ be_nested_str_weak(_p), + /* K36 */ be_nested_str_weak(page_dir_to), + /* K37 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25i_X22_X3A_X22out_X22_X7D_X7D), + /* K38 */ be_nested_str_weak(lvh_page_cur_idx), + /* K39 */ be_nested_str_weak(tasmota), + /* K40 */ be_nested_str_weak(set_timer), + /* K41 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25i_X22_X3A_X22in_X22_X7D_X7D), + /* K42 */ be_nested_str_weak(screen_load), + /* K43 */ be_nested_str_weak(show_anim), + /* K44 */ be_nested_str_weak(SCR_LOAD_ANIM_NONE), + /* K45 */ be_nested_str_weak(screen_load_anim), + /* K46 */ be_nested_str_weak(_remove_page), }; extern const bclass be_class_lvh_page; /******************************************************************** -** Solidified function: id +** Solidified function: get_clear ********************************************************************/ -be_local_closure(class_lvh_page_id, /* name */ +be_local_closure(class_lvh_page_get_clear, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 0, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ), + }), + 1, /* has constants */ + &be_ktab_class_lvh_page, /* shared constants */ + be_str_weak(get_clear), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x84040000, // 0002 CLOSURE R1 P0 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: member +********************************************************************/ +be_local_closure(class_lvh_page_member, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_lvh_page, /* shared constants */ + be_str_weak(member), + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0xA40A0200, // 0000 IMPORT R2 K1 + 0xA40E0400, // 0001 IMPORT R3 K2 + 0x8C100503, // 0002 GETMET R4 R2 K3 + 0x5C180200, // 0003 MOVE R6 R1 + 0x581C0004, // 0004 LDCONST R7 K4 + 0x7C100600, // 0005 CALL R4 3 + 0x74120004, // 0006 JMPT R4 #000C + 0x8C100503, // 0007 GETMET R4 R2 K3 + 0x5C180200, // 0008 MOVE R6 R1 + 0x581C0005, // 0009 LDCONST R7 K5 + 0x7C100600, // 000A CALL R4 3 + 0x78120000, // 000B JMPF R4 #000D + 0x80000800, // 000C RET 0 + 0x8C100706, // 000D GETMET R4 R3 K6 + 0x5C180000, // 000E MOVE R6 R0 + 0x001E0A01, // 000F ADD R7 K5 R1 + 0x7C100600, // 0010 CALL R4 3 + 0x60140004, // 0011 GETGBL R5 G4 + 0x5C180800, // 0012 MOVE R6 R4 + 0x7C140200, // 0013 CALL R5 1 + 0x1C140B07, // 0014 EQ R5 R5 K7 + 0x78160003, // 0015 JMPF R5 #001A + 0x5C140800, // 0016 MOVE R5 R4 + 0x5C180000, // 0017 MOVE R6 R0 + 0x7C140200, // 0018 CALL R5 1 + 0x80040A00, // 0019 RET 1 R5 + 0x6014000B, // 001A GETGBL R5 G11 + 0x58180008, // 001B LDCONST R6 K8 + 0x7C140200, // 001C CALL R5 1 + 0x80040A00, // 001D RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: _clear +********************************************************************/ +be_local_closure(class_lvh_page__clear, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_lvh_page, /* shared constants */ + be_str_weak(_clear), + &be_const_str_solidified, + ( &(const binstruction[41]) { /* code */ + 0x60040012, // 0000 GETGBL R1 G18 + 0x7C040000, // 0001 CALL R1 0 + 0x60080010, // 0002 GETGBL R2 G16 + 0x880C0109, // 0003 GETMBR R3 R0 K9 + 0x8C0C070A, // 0004 GETMET R3 R3 K10 + 0x7C0C0200, // 0005 CALL R3 1 + 0x7C080200, // 0006 CALL R2 1 + 0xA8020005, // 0007 EXBLK 0 #000E + 0x5C0C0400, // 0008 MOVE R3 R2 + 0x7C0C0000, // 0009 CALL R3 0 + 0x8C10030B, // 000A GETMET R4 R1 K11 + 0x5C180600, // 000B MOVE R6 R3 + 0x7C100400, // 000C CALL R4 2 + 0x7001FFF9, // 000D JMP #0008 + 0x5808000C, // 000E LDCONST R2 K12 + 0xAC080200, // 000F CATCH R2 1 0 + 0xB0080000, // 0010 RAISE 2 R0 R0 + 0x5808000D, // 0011 LDCONST R2 K13 + 0x600C000C, // 0012 GETGBL R3 G12 + 0x5C100200, // 0013 MOVE R4 R1 + 0x7C0C0200, // 0014 CALL R3 1 + 0x140C0403, // 0015 LT R3 R2 R3 + 0x780E000D, // 0016 JMPF R3 #0025 + 0x940C0202, // 0017 GETIDX R3 R1 R2 + 0x2010070D, // 0018 NE R4 R3 K13 + 0x78120008, // 0019 JMPF R4 #0023 + 0x88100109, // 001A GETMBR R4 R0 K9 + 0x8C10090E, // 001B GETMET R4 R4 K14 + 0x5C180600, // 001C MOVE R6 R3 + 0x7C100400, // 001D CALL R4 2 + 0x78120003, // 001E JMPF R4 #0023 + 0x88100109, // 001F GETMBR R4 R0 K9 + 0x94100803, // 0020 GETIDX R4 R4 R3 + 0x8C10090F, // 0021 GETMET R4 R4 K15 + 0x7C100200, // 0022 CALL R4 1 + 0x00080510, // 0023 ADD R2 R2 K16 + 0x7001FFEC, // 0024 JMP #0012 + 0x600C0013, // 0025 GETGBL R3 G19 + 0x7C0C0000, // 0026 CALL R3 0 + 0x90021203, // 0027 SETMBR R0 K9 R3 + 0x80000000, // 0028 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_scr +********************************************************************/ +be_local_closure(class_lvh_page_get_scr, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -10265,10 +10448,10 @@ be_local_closure(class_lvh_page_id, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(id), + be_str_weak(get_scr), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88040111, // 0000 GETMBR R1 R0 K17 0x80040200, // 0001 RET 1 R1 }) ) @@ -10276,6 +10459,50 @@ be_local_closure(class_lvh_page_id, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: get_delete +********************************************************************/ +be_local_closure(class_lvh_page_get_delete, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 0, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ), + }), + 1, /* has constants */ + &be_ktab_class_lvh_page, /* shared constants */ + be_str_weak(get_delete), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C04010F, // 0000 GETMET R1 R0 K15 + 0x7C040200, // 0001 CALL R1 1 + 0x84040000, // 0002 CLOSURE R1 P0 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: remove_obj ********************************************************************/ @@ -10293,23 +10520,23 @@ be_local_closure(class_lvh_page_remove_obj, /* name */ be_str_weak(remove_obj), &be_const_str_solidified, ( &(const binstruction[20]) { /* code */ - 0x88080101, // 0000 GETMBR R2 R0 K1 - 0x8C080502, // 0001 GETMET R2 R2 K2 + 0x88080109, // 0000 GETMBR R2 R0 K9 + 0x8C080512, // 0001 GETMET R2 R2 K18 0x5C100200, // 0002 MOVE R4 R1 0x7C080400, // 0003 CALL R2 2 - 0x880C0101, // 0004 GETMBR R3 R0 K1 - 0x8C0C0703, // 0005 GETMET R3 R3 K3 + 0x880C0109, // 0004 GETMBR R3 R0 K9 + 0x8C0C0713, // 0005 GETMET R3 R3 K19 0x5C140200, // 0006 MOVE R5 R1 0x7C0C0400, // 0007 CALL R3 2 0x780A0009, // 0008 JMPF R2 #0013 0x600C0018, // 0009 GETGBL R3 G24 - 0x58100004, // 000A LDCONST R4 K4 - 0x88140505, // 000B GETMBR R5 R2 K5 - 0x8C140B06, // 000C GETMET R5 R5 K6 + 0x58100014, // 000A LDCONST R4 K20 + 0x88140515, // 000B GETMBR R5 R2 K21 + 0x8C140B16, // 000C GETMET R5 R5 K22 0x7C140200, // 000D CALL R5 1 0x5C180200, // 000E MOVE R6 R1 0x7C0C0600, // 000F CALL R3 3 - 0xB8120E00, // 0010 GETNGBL R4 K7 + 0xB8122E00, // 0010 GETNGBL R4 K23 0x4C140000, // 0011 LDNIL R5 0x90100605, // 0012 SETMBR R4 R3 R5 0x80000000, // 0013 RET 0 @@ -10320,12 +10547,12 @@ be_local_closure(class_lvh_page_remove_obj, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: get_obj ********************************************************************/ -be_local_closure(class_lvh_page_init, /* name */ +be_local_closure(class_lvh_page_get_obj, /* name */ be_nested_proto( - 10, /* nstack */ - 3, /* argc */ + 5, /* nstack */ + 2, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -10333,68 +10560,14 @@ be_local_closure(class_lvh_page_init, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(init), + be_str_weak(get_obj), &be_const_str_solidified, - ( &(const binstruction[59]) { /* code */ - 0xA40E0E00, // 0000 IMPORT R3 K7 - 0x90021002, // 0001 SETMBR R0 K8 R2 - 0x60100009, // 0002 GETGBL R4 G9 - 0x5C140200, // 0003 MOVE R5 R1 - 0x7C100200, // 0004 CALL R4 1 - 0x5C040800, // 0005 MOVE R1 R4 - 0x4C100000, // 0006 LDNIL R4 - 0x1C100204, // 0007 EQ R4 R1 R4 - 0x78120000, // 0008 JMPF R4 #000A - 0x58040009, // 0009 LDCONST R1 K9 - 0x90020001, // 000A SETMBR R0 K0 R1 - 0x60100013, // 000B GETGBL R4 G19 - 0x7C100000, // 000C CALL R4 0 - 0x90020204, // 000D SETMBR R0 K1 R4 - 0x1C10030A, // 000E EQ R4 R1 K10 - 0x78120004, // 000F JMPF R4 #0015 - 0xB8121800, // 0010 GETNGBL R4 K12 - 0x8C10090D, // 0011 GETMET R4 R4 K13 - 0x7C100200, // 0012 CALL R4 1 - 0x90021604, // 0013 SETMBR R0 K11 R4 - 0x7002000F, // 0014 JMP #0025 - 0xB8121800, // 0015 GETNGBL R4 K12 - 0x8C10090E, // 0016 GETMET R4 R4 K14 - 0x5818000A, // 0017 LDCONST R6 K10 - 0x7C100400, // 0018 CALL R4 2 - 0x90021604, // 0019 SETMBR R0 K11 R4 - 0xB8121800, // 001A GETNGBL R4 K12 - 0x8C10090F, // 001B GETMET R4 R4 K15 - 0x7C100200, // 001C CALL R4 1 - 0x8C100910, // 001D GETMET R4 R4 K16 - 0x5818000A, // 001E LDCONST R6 K10 - 0x7C100400, // 001F CALL R4 2 - 0x8814010B, // 0020 GETMBR R5 R0 K11 - 0x8C140B11, // 0021 GETMET R5 R5 K17 - 0x5C1C0800, // 0022 MOVE R7 R4 - 0x5820000A, // 0023 LDCONST R8 K10 - 0x7C140600, // 0024 CALL R5 3 - 0x88100108, // 0025 GETMBR R4 R0 K8 - 0x88100912, // 0026 GETMBR R4 R4 K18 - 0x5C140800, // 0027 MOVE R5 R4 - 0x4C180000, // 0028 LDNIL R6 - 0x5C1C0000, // 0029 MOVE R7 R0 - 0x4C200000, // 002A LDNIL R8 - 0x8824010B, // 002B GETMBR R9 R0 K11 - 0x7C140800, // 002C CALL R5 4 - 0x88180101, // 002D GETMBR R6 R0 K1 - 0x981A1405, // 002E SETIDX R6 K10 R5 - 0x60180008, // 002F GETGBL R6 G8 - 0x881C0100, // 0030 GETMBR R7 R0 K0 - 0x7C180200, // 0031 CALL R6 1 - 0x001A2606, // 0032 ADD R6 K19 R6 - 0x900C0C00, // 0033 SETMBR R3 R6 R0 - 0x60180008, // 0034 GETGBL R6 G8 - 0x881C0100, // 0035 GETMBR R7 R0 K0 - 0x7C180200, // 0036 CALL R6 1 - 0x001A2606, // 0037 ADD R6 K19 R6 - 0x00180D14, // 0038 ADD R6 R6 K20 - 0x900C0C05, // 0039 SETMBR R3 R6 R5 - 0x80000000, // 003A RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0x88080109, // 0000 GETMBR R2 R0 K9 + 0x8C080512, // 0001 GETMET R2 R2 K18 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x80040400, // 0004 RET 1 R2 }) ) ); @@ -10418,16 +10591,16 @@ be_local_closure(class_lvh_page_add_obj, /* name */ be_str_weak(add_obj), &be_const_str_solidified, ( &(const binstruction[12]) { /* code */ - 0x880C0101, // 0000 GETMBR R3 R0 K1 + 0x880C0109, // 0000 GETMBR R3 R0 K9 0x980C0202, // 0001 SETIDX R3 R1 R2 0x600C0018, // 0002 GETGBL R3 G24 - 0x58100004, // 0003 LDCONST R4 K4 - 0x88140505, // 0004 GETMBR R5 R2 K5 - 0x8C140B06, // 0005 GETMET R5 R5 K6 + 0x58100014, // 0003 LDCONST R4 K20 + 0x88140515, // 0004 GETMBR R5 R2 K21 + 0x8C140B16, // 0005 GETMET R5 R5 K22 0x7C140200, // 0006 CALL R5 1 0x5C180200, // 0007 MOVE R6 R1 0x7C0C0600, // 0008 CALL R3 3 - 0xB8120E00, // 0009 GETNGBL R4 K7 + 0xB8122E00, // 0009 GETNGBL R4 K23 0x90100602, // 000A SETMBR R4 R3 R2 0x80000000, // 000B RET 0 }) @@ -10437,12 +10610,12 @@ be_local_closure(class_lvh_page_add_obj, /* name */ /******************************************************************** -** Solidified function: delete +** Solidified function: init ********************************************************************/ -be_local_closure(class_lvh_page_delete, /* name */ +be_local_closure(class_lvh_page_init, /* name */ be_nested_proto( - 7, /* nstack */ - 1, /* argc */ + 10, /* nstack */ + 3, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -10450,54 +10623,67 @@ be_local_closure(class_lvh_page_delete, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(delete), + be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[45]) { /* code */ - 0x60040012, // 0000 GETGBL R1 G18 - 0x7C040000, // 0001 CALL R1 0 - 0x60080010, // 0002 GETGBL R2 G16 - 0x880C0101, // 0003 GETMBR R3 R0 K1 - 0x8C0C0715, // 0004 GETMET R3 R3 K21 - 0x7C0C0200, // 0005 CALL R3 1 - 0x7C080200, // 0006 CALL R2 1 - 0xA8020005, // 0007 EXBLK 0 #000E - 0x5C0C0400, // 0008 MOVE R3 R2 - 0x7C0C0000, // 0009 CALL R3 0 - 0x8C100316, // 000A GETMET R4 R1 K22 - 0x5C180600, // 000B MOVE R6 R3 - 0x7C100400, // 000C CALL R4 2 - 0x7001FFF9, // 000D JMP #0008 - 0x58080017, // 000E LDCONST R2 K23 - 0xAC080200, // 000F CATCH R2 1 0 - 0xB0080000, // 0010 RAISE 2 R0 R0 - 0x5808000A, // 0011 LDCONST R2 K10 - 0x600C000C, // 0012 GETGBL R3 G12 - 0x5C100200, // 0013 MOVE R4 R1 - 0x7C0C0200, // 0014 CALL R3 1 - 0x140C0403, // 0015 LT R3 R2 R3 - 0x780E000D, // 0016 JMPF R3 #0025 - 0x940C0202, // 0017 GETIDX R3 R1 R2 - 0x2010070A, // 0018 NE R4 R3 K10 - 0x78120008, // 0019 JMPF R4 #0023 - 0x88100101, // 001A GETMBR R4 R0 K1 - 0x8C100918, // 001B GETMET R4 R4 K24 - 0x5C180600, // 001C MOVE R6 R3 - 0x7C100400, // 001D CALL R4 2 - 0x78120003, // 001E JMPF R4 #0023 - 0x88100101, // 001F GETMBR R4 R0 K1 - 0x94100803, // 0020 GETIDX R4 R4 R3 - 0x8C100919, // 0021 GETMET R4 R4 K25 - 0x7C100200, // 0022 CALL R4 1 - 0x00080509, // 0023 ADD R2 R2 K9 - 0x7001FFEC, // 0024 JMP #0012 - 0x600C0013, // 0025 GETGBL R3 G19 - 0x7C0C0000, // 0026 CALL R3 0 - 0x90020203, // 0027 SETMBR R0 K1 R3 - 0x880C0108, // 0028 GETMBR R3 R0 K8 - 0x8C0C071A, // 0029 GETMET R3 R3 K26 - 0x88140100, // 002A GETMBR R5 R0 K0 - 0x7C0C0400, // 002B CALL R3 2 - 0x80000000, // 002C RET 0 + ( &(const binstruction[58]) { /* code */ + 0xA40E2E00, // 0000 IMPORT R3 K23 + 0x90023002, // 0001 SETMBR R0 K24 R2 + 0x60100009, // 0002 GETGBL R4 G9 + 0x5C140200, // 0003 MOVE R5 R1 + 0x7C100200, // 0004 CALL R4 1 + 0x5C040800, // 0005 MOVE R1 R4 + 0x4C100000, // 0006 LDNIL R4 + 0x1C100204, // 0007 EQ R4 R1 R4 + 0x78120000, // 0008 JMPF R4 #000A + 0x58040010, // 0009 LDCONST R1 K16 + 0x90023201, // 000A SETMBR R0 K25 R1 + 0x60100013, // 000B GETGBL R4 G19 + 0x7C100000, // 000C CALL R4 0 + 0x90021204, // 000D SETMBR R0 K9 R4 + 0x1C10030D, // 000E EQ R4 R1 K13 + 0x78120004, // 000F JMPF R4 #0015 + 0xB8123400, // 0010 GETNGBL R4 K26 + 0x8C10091B, // 0011 GETMET R4 R4 K27 + 0x7C100200, // 0012 CALL R4 1 + 0x90022204, // 0013 SETMBR R0 K17 R4 + 0x7002000F, // 0014 JMP #0025 + 0xB8123400, // 0015 GETNGBL R4 K26 + 0x8C10091C, // 0016 GETMET R4 R4 K28 + 0x5818000D, // 0017 LDCONST R6 K13 + 0x7C100400, // 0018 CALL R4 2 + 0x90022204, // 0019 SETMBR R0 K17 R4 + 0xB8123400, // 001A GETNGBL R4 K26 + 0x8C10091D, // 001B GETMET R4 R4 K29 + 0x7C100200, // 001C CALL R4 1 + 0x8C10091E, // 001D GETMET R4 R4 K30 + 0x5818000D, // 001E LDCONST R6 K13 + 0x7C100400, // 001F CALL R4 2 + 0x88140111, // 0020 GETMBR R5 R0 K17 + 0x8C140B1F, // 0021 GETMET R5 R5 K31 + 0x5C1C0800, // 0022 MOVE R7 R4 + 0x5820000D, // 0023 LDCONST R8 K13 + 0x7C140600, // 0024 CALL R5 3 + 0x88100118, // 0025 GETMBR R4 R0 K24 + 0x88100920, // 0026 GETMBR R4 R4 K32 + 0x5C140800, // 0027 MOVE R5 R4 + 0x4C180000, // 0028 LDNIL R6 + 0x5C1C0000, // 0029 MOVE R7 R0 + 0x4C200000, // 002A LDNIL R8 + 0x88240111, // 002B GETMBR R9 R0 K17 + 0x7C140800, // 002C CALL R5 4 + 0x88180109, // 002D GETMBR R6 R0 K9 + 0x981A1A05, // 002E SETIDX R6 K13 R5 + 0x60180018, // 002F GETGBL R6 G24 + 0x581C0021, // 0030 LDCONST R7 K33 + 0x88200119, // 0031 GETMBR R8 R0 K25 + 0x7C180400, // 0032 CALL R6 2 + 0x900C0C00, // 0033 SETMBR R3 R6 R0 + 0x60180018, // 0034 GETGBL R6 G24 + 0x581C0022, // 0035 LDCONST R7 K34 + 0x88200119, // 0036 GETMBR R8 R0 K25 + 0x7C180400, // 0037 CALL R6 2 + 0x900C0C05, // 0038 SETMBR R3 R6 R5 + 0x80000000, // 0039 RET 0 }) ) ); @@ -10572,18 +10758,18 @@ be_local_closure(class_lvh_page_show, /* name */ be_str_weak(show), &be_const_str_solidified, ( &(const binstruction[73]) { /* code */ - 0x880C010B, // 0000 GETMBR R3 R0 K11 + 0x880C0111, // 0000 GETMBR R3 R0 K17 0x4C100000, // 0001 LDNIL R4 0x1C0C0604, // 0002 EQ R3 R3 R4 0x780E0001, // 0003 JMPF R3 #0006 0x4C0C0000, // 0004 LDNIL R3 0x80040600, // 0005 RET 1 R3 - 0x880C010B, // 0006 GETMBR R3 R0 K11 - 0x880C071B, // 0007 GETMBR R3 R3 K27 - 0xB8121800, // 0008 GETNGBL R4 K12 - 0x8C10090F, // 0009 GETMET R4 R4 K15 + 0x880C0111, // 0006 GETMBR R3 R0 K17 + 0x880C0723, // 0007 GETMBR R3 R3 K35 + 0xB8123400, // 0008 GETNGBL R4 K26 + 0x8C10091D, // 0009 GETMET R4 R4 K29 0x7C100200, // 000A CALL R4 1 - 0x8810091B, // 000B GETMBR R4 R4 K27 + 0x88100923, // 000B GETMBR R4 R4 K35 0x1C0C0604, // 000C EQ R3 R3 R4 0x780E0000, // 000D JMPF R3 #000F 0x80000600, // 000E RET 0 @@ -10594,53 +10780,53 @@ be_local_closure(class_lvh_page_show, /* name */ 0x4C0C0000, // 0013 LDNIL R3 0x1C0C0203, // 0014 EQ R3 R1 R3 0x780E0005, // 0015 JMPF R3 #001C - 0x880C0108, // 0016 GETMBR R3 R0 K8 - 0x8C0C071C, // 0017 GETMET R3 R3 K28 - 0x8C140106, // 0018 GETMET R5 R0 K6 + 0x880C0118, // 0016 GETMBR R3 R0 K24 + 0x8C0C0724, // 0017 GETMET R3 R3 K36 + 0x8C140116, // 0018 GETMET R5 R0 K22 0x7C140200, // 0019 CALL R5 1 0x7C0C0400, // 001A CALL R3 2 0x5C040600, // 001B MOVE R1 R3 0x600C0018, // 001C GETGBL R3 G24 - 0x5810001D, // 001D LDCONST R4 K29 - 0x88140108, // 001E GETMBR R5 R0 K8 - 0x88140B1E, // 001F GETMBR R5 R5 K30 + 0x58100025, // 001D LDCONST R4 K37 + 0x88140118, // 001E GETMBR R5 R0 K24 + 0x88140B26, // 001F GETMBR R5 R5 K38 0x7C0C0400, // 0020 CALL R3 2 - 0xB8123E00, // 0021 GETNGBL R4 K31 - 0x8C100920, // 0022 GETMET R4 R4 K32 - 0x5818000A, // 0023 LDCONST R6 K10 + 0xB8124E00, // 0021 GETNGBL R4 K39 + 0x8C100928, // 0022 GETMET R4 R4 K40 + 0x5818000D, // 0023 LDCONST R6 K13 0x841C0000, // 0024 CLOSURE R7 P0 0x7C100600, // 0025 CALL R4 3 0x60100018, // 0026 GETGBL R4 G24 - 0x58140021, // 0027 LDCONST R5 K33 - 0x88180100, // 0028 GETMBR R6 R0 K0 + 0x58140029, // 0027 LDCONST R5 K41 + 0x88180119, // 0028 GETMBR R6 R0 K25 0x7C100400, // 0029 CALL R4 2 - 0xB8163E00, // 002A GETNGBL R5 K31 - 0x8C140B20, // 002B GETMET R5 R5 K32 - 0x581C000A, // 002C LDCONST R7 K10 + 0xB8164E00, // 002A GETNGBL R5 K39 + 0x8C140B28, // 002B GETMET R5 R5 K40 + 0x581C000D, // 002C LDCONST R7 K13 0x84200001, // 002D CLOSURE R8 P1 0x7C140600, // 002E CALL R5 3 - 0x88140108, // 002F GETMBR R5 R0 K8 - 0x88180100, // 0030 GETMBR R6 R0 K0 - 0x90163C06, // 0031 SETMBR R5 K30 R6 - 0x1C14030A, // 0032 EQ R5 R1 K10 + 0x88140118, // 002F GETMBR R5 R0 K24 + 0x88180119, // 0030 GETMBR R6 R0 K25 + 0x90164C06, // 0031 SETMBR R5 K38 R6 + 0x1C14030D, // 0032 EQ R5 R1 K13 0x78160004, // 0033 JMPF R5 #0039 - 0xB8161800, // 0034 GETNGBL R5 K12 - 0x8C140B22, // 0035 GETMET R5 R5 K34 - 0x881C010B, // 0036 GETMBR R7 R0 K11 + 0xB8163400, // 0034 GETNGBL R5 K26 + 0x8C140B2A, // 0035 GETMET R5 R5 K42 + 0x881C0111, // 0036 GETMBR R7 R0 K17 0x7C140400, // 0037 CALL R5 2 0x7002000D, // 0038 JMP #0047 - 0x88140123, // 0039 GETMBR R5 R0 K35 - 0x8C140B02, // 003A GETMET R5 R5 K2 + 0x8814012B, // 0039 GETMBR R5 R0 K43 + 0x8C140B12, // 003A GETMET R5 R5 K18 0x5C1C0200, // 003B MOVE R7 R1 - 0xB8221800, // 003C GETNGBL R8 K12 - 0x88201124, // 003D GETMBR R8 R8 K36 + 0xB8223400, // 003C GETNGBL R8 K26 + 0x8820112C, // 003D GETMBR R8 R8 K44 0x7C140600, // 003E CALL R5 3 - 0xB81A1800, // 003F GETNGBL R6 K12 - 0x8C180D25, // 0040 GETMET R6 R6 K37 - 0x8820010B, // 0041 GETMBR R8 R0 K11 + 0xB81A3400, // 003F GETNGBL R6 K26 + 0x8C180D2D, // 0040 GETMET R6 R6 K45 + 0x88200111, // 0041 GETMBR R8 R0 K17 0x5C240A00, // 0042 MOVE R9 R5 0x5C280400, // 0043 MOVE R10 R2 - 0x582C000A, // 0044 LDCONST R11 K10 + 0x582C000D, // 0044 LDCONST R11 K13 0x50300000, // 0045 LDBOOL R12 0 0 0x7C180C00, // 0046 CALL R6 6 0xA0000000, // 0047 CLOSE R0 @@ -10652,12 +10838,12 @@ be_local_closure(class_lvh_page_show, /* name */ /******************************************************************** -** Solidified function: get_obj +** Solidified function: _delete ********************************************************************/ -be_local_closure(class_lvh_page_get_obj, /* name */ +be_local_closure(class_lvh_page__delete, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 4, /* nstack */ + 1, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -10665,14 +10851,16 @@ be_local_closure(class_lvh_page_get_obj, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(get_obj), + be_str_weak(_delete), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88080101, // 0000 GETMBR R2 R0 K1 - 0x8C080502, // 0001 GETMET R2 R2 K2 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x80040400, // 0004 RET 1 R2 + ( &(const binstruction[ 7]) { /* code */ + 0x88040118, // 0000 GETMBR R1 R0 K24 + 0x8C04032E, // 0001 GETMET R1 R1 K46 + 0x880C0119, // 0002 GETMBR R3 R0 K25 + 0x7C040400, // 0003 CALL R1 2 + 0x8C040100, // 0004 GETMET R1 R0 K0 + 0x7C040200, // 0005 CALL R1 1 + 0x80000000, // 0006 RET 0 }) ) ); @@ -10680,9 +10868,9 @@ be_local_closure(class_lvh_page_get_obj, /* name */ /******************************************************************** -** Solidified function: get_scr +** Solidified function: id ********************************************************************/ -be_local_closure(class_lvh_page_get_scr, /* name */ +be_local_closure(class_lvh_page_id, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -10693,10 +10881,10 @@ be_local_closure(class_lvh_page_get_scr, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_lvh_page, /* shared constants */ - be_str_weak(get_scr), + be_str_weak(id), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ - 0x8804010B, // 0000 GETMBR R1 R0 K11 + 0x88040119, // 0000 GETMBR R1 R0 K25 0x80040200, // 0001 RET 1 R1 }) ) @@ -10710,13 +10898,9 @@ be_local_closure(class_lvh_page_get_scr, /* name */ be_local_class(lvh_page, 7, NULL, - be_nested_map(16, + be_nested_map(20, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(id, 5), be_const_closure(class_lvh_page_id_closure) }, - { be_const_key_weak(_obj_id, -1), be_const_var(0) }, - { be_const_key_weak(back, -1), be_const_var(6) }, - { be_const_key_weak(remove_obj, 14), be_const_closure(class_lvh_page_remove_obj_closure) }, - { be_const_key_weak(show_anim, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + { be_const_key_weak(show_anim, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { be_const_map( * be_nested_map(5, ( (struct bmapnode*) &(const bmapnode[]) { { be_const_key_int(0, 3), be_const_int(0) }, @@ -10725,23 +10909,31 @@ be_local_class(lvh_page, { be_const_key_int(-1, -1), be_const_int(6) }, { be_const_key_int(-2, -1), be_const_int(7) }, })) ) } )) }, - { be_const_key_weak(prev, -1), be_const_var(4) }, - { be_const_key_weak(add_obj, -1), be_const_closure(class_lvh_page_add_obj_closure) }, - { be_const_key_weak(get_scr, -1), be_const_closure(class_lvh_page_get_scr_closure) }, + { be_const_key_weak(id, 3), be_const_closure(class_lvh_page_id_closure) }, + { be_const_key_weak(_obj_id, -1), be_const_var(0) }, + { be_const_key_weak(show, 18), be_const_closure(class_lvh_page_show_closure) }, + { be_const_key_weak(_lv_scr, 19), be_const_var(2) }, + { be_const_key_weak(get_clear, 2), be_const_closure(class_lvh_page_get_clear_closure) }, + { be_const_key_weak(back, -1), be_const_var(6) }, + { be_const_key_weak(get_delete, -1), be_const_closure(class_lvh_page_get_delete_closure) }, + { be_const_key_weak(remove_obj, 4), be_const_closure(class_lvh_page_remove_obj_closure) }, + { be_const_key_weak(_hm, -1), be_const_var(3) }, + { be_const_key_weak(_page_id, 8), be_const_var(1) }, + { be_const_key_weak(member, 10), be_const_closure(class_lvh_page_member_closure) }, { be_const_key_weak(next, -1), be_const_var(5) }, { be_const_key_weak(get_obj, -1), be_const_closure(class_lvh_page_get_obj_closure) }, - { be_const_key_weak(delete, -1), be_const_closure(class_lvh_page_delete_closure) }, - { be_const_key_weak(_lv_scr, -1), be_const_var(2) }, - { be_const_key_weak(show, 7), be_const_closure(class_lvh_page_show_closure) }, - { be_const_key_weak(_hm, 9), be_const_var(3) }, - { be_const_key_weak(_page_id, 15), be_const_var(1) }, + { be_const_key_weak(add_obj, -1), be_const_closure(class_lvh_page_add_obj_closure) }, { be_const_key_weak(init, -1), be_const_closure(class_lvh_page_init_closure) }, + { be_const_key_weak(prev, 0), be_const_var(4) }, + { be_const_key_weak(_delete, -1), be_const_closure(class_lvh_page__delete_closure) }, + { be_const_key_weak(get_scr, -1), be_const_closure(class_lvh_page_get_scr_closure) }, + { be_const_key_weak(_clear, -1), be_const_closure(class_lvh_page__clear_closure) }, })), be_str_weak(lvh_page) ); extern const bclass be_class_HASPmota; -// compact class 'HASPmota' ktab size: 120, total: 180 (saved 480 bytes) -static const bvalue be_ktab_class_HASPmota[120] = { +// compact class 'HASPmota' ktab size: 122, total: 190 (saved 544 bytes) +static const bvalue be_ktab_class_HASPmota[122] = { /* K0 */ be_const_class(be_class_HASPmota), /* K1 */ be_nested_str_weak(introspect), /* K2 */ be_nested_str_weak(get), @@ -10807,61 +10999,63 @@ static const bvalue be_ktab_class_HASPmota[120] = { /* K62 */ be_nested_str_weak(pages_list_sorted), /* K63 */ be_nested_str_weak(no_X20page_X20object_X20defined), /* K64 */ be_nested_str_weak(show), - /* K65 */ be_nested_str_weak(match), - /* K66 */ be_nested_str_weak(path), - /* K67 */ be_nested_str_weak(def_templ_name), - /* K68 */ be_nested_str_weak(exists), - /* K69 */ be_nested_str_weak(file_X20_X27), - /* K70 */ be_nested_str_weak(_X27_X20not_X20found), - /* K71 */ be_nested_str_weak(io_erorr), - /* K72 */ be_nested_str_weak(start), - /* K73 */ be_nested_str_weak(dark), - /* K74 */ be_nested_str_weak(hres), - /* K75 */ be_nested_str_weak(get_hor_res), - /* K76 */ be_nested_str_weak(vres), - /* K77 */ be_nested_str_weak(get_ver_res), - /* K78 */ be_nested_str_weak(scr), - /* K79 */ be_nested_str_weak(scr_act), - /* K80 */ be_nested_str_weak(r16), - /* K81 */ be_nested_str_weak(font_embedded), - /* K82 */ be_nested_str_weak(robotocondensed), - /* K83 */ be_nested_str_weak(montserrat), - /* K84 */ be_nested_str_weak(theme_haspmota_init), - /* K85 */ be_nested_str_weak(color), - /* K86 */ be_const_int(16711935), - /* K87 */ be_const_int(3158064), - /* K88 */ be_nested_str_weak(get_disp), - /* K89 */ be_nested_str_weak(set_theme), - /* K90 */ be_nested_str_weak(set_style_bg_color), - /* K91 */ be_const_int(16777215), - /* K92 */ be_nested_str_weak(theme_apply), - /* K93 */ be_nested_str_weak(layer_top), - /* K94 */ be_nested_str_weak(set_style_bg_opa), - /* K95 */ be_nested_str_weak(_load), - /* K96 */ be_nested_str_weak(global), - /* K97 */ be_nested_str_weak(obj), - /* K98 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20_X25s_X20for_X20_X27obj_X27_X3A_X20_X25s), - /* K99 */ be_nested_str_weak(get_obj), - /* K100 */ be_nested_str_weak(parentid), - /* K101 */ be_nested_str_weak(get_scr), - /* K102 */ be_nested_str_weak(lvh_), - /* K103 */ be_nested_str_weak(class), - /* K104 */ be_nested_str_weak(lvh_obj), - /* K105 */ be_nested_str_weak(module), - /* K106 */ be_nested_str_weak(HSP_X3A_X20Cannot_X20find_X20object_X20of_X20type_X20_X25s), - /* K107 */ be_nested_str_weak(add_obj), - /* K108 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X3A_X27_X25s_X27_X20for_X20_X27id_X27_X3A0), - /* K109 */ be_nested_str_weak(post_config), - /* K110 */ be_nested_str_weak(berry_run), - /* K111 */ be_nested_str_weak(nil), - /* K112 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K113 */ be_nested_str_weak(function), - /* K114 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K115 */ be_nested_str_weak(event), - /* K116 */ be_nested_str_weak(_p), - /* K117 */ be_nested_str_weak(lv_event), - /* K118 */ be_nested_str_weak(get_user_data), - /* K119 */ be_nested_str_weak(fromptr), + /* K65 */ be_nested_str_weak(delete), + /* K66 */ be_nested_str_weak(match), + /* K67 */ be_nested_str_weak(path), + /* K68 */ be_nested_str_weak(def_templ_name), + /* K69 */ be_nested_str_weak(exists), + /* K70 */ be_nested_str_weak(file_X20_X27), + /* K71 */ be_nested_str_weak(_X27_X20not_X20found), + /* K72 */ be_nested_str_weak(io_erorr), + /* K73 */ be_nested_str_weak(start), + /* K74 */ be_nested_str_weak(dark), + /* K75 */ be_nested_str_weak(hres), + /* K76 */ be_nested_str_weak(get_hor_res), + /* K77 */ be_nested_str_weak(vres), + /* K78 */ be_nested_str_weak(get_ver_res), + /* K79 */ be_nested_str_weak(scr), + /* K80 */ be_nested_str_weak(scr_act), + /* K81 */ be_nested_str_weak(r16), + /* K82 */ be_nested_str_weak(font_embedded), + /* K83 */ be_nested_str_weak(robotocondensed), + /* K84 */ be_nested_str_weak(montserrat), + /* K85 */ be_nested_str_weak(theme_haspmota_init), + /* K86 */ be_nested_str_weak(color), + /* K87 */ be_const_int(16711935), + /* K88 */ be_const_int(3158064), + /* K89 */ be_nested_str_weak(get_disp), + /* K90 */ be_nested_str_weak(set_theme), + /* K91 */ be_nested_str_weak(set_style_bg_color), + /* K92 */ be_const_int(16777215), + /* K93 */ be_nested_str_weak(theme_apply), + /* K94 */ be_nested_str_weak(layer_top), + /* K95 */ be_nested_str_weak(set_style_bg_opa), + /* K96 */ be_nested_str_weak(_load), + /* K97 */ be_nested_str_weak(global), + /* K98 */ be_nested_str_weak(p_X25s), + /* K99 */ be_nested_str_weak(obj), + /* K100 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20_X25s_X20for_X20_X27obj_X27_X3A_X20_X25s), + /* K101 */ be_nested_str_weak(get_obj), + /* K102 */ be_nested_str_weak(parentid), + /* K103 */ be_nested_str_weak(get_scr), + /* K104 */ be_nested_str_weak(lvh_), + /* K105 */ be_nested_str_weak(class), + /* K106 */ be_nested_str_weak(lvh_obj), + /* K107 */ be_nested_str_weak(module), + /* K108 */ be_nested_str_weak(HSP_X3A_X20Cannot_X20find_X20object_X20of_X20type_X20_X25s), + /* K109 */ be_nested_str_weak(add_obj), + /* K110 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X3A_X27_X25s_X27_X20for_X20_X27id_X27_X3A0), + /* K111 */ be_nested_str_weak(post_config), + /* K112 */ be_nested_str_weak(berry_run), + /* K113 */ be_nested_str_weak(nil), + /* K114 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K115 */ be_nested_str_weak(function), + /* K116 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K117 */ be_nested_str_weak(event), + /* K118 */ be_nested_str_weak(_p), + /* K119 */ be_nested_str_weak(lv_event), + /* K120 */ be_nested_str_weak(get_user_data), + /* K121 */ be_nested_str_weak(fromptr), }; @@ -11436,89 +11630,157 @@ be_local_closure(class_HASPmota_page_dir_to, /* name */ ********************************************************************/ be_local_closure(class_HASPmota_page_show, /* name */ be_nested_proto( - 8, /* nstack */ - 2, /* argc */ + 13, /* nstack */ + 4, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + 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[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + }), + be_str_weak(to_page_resolve), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x200C0003, // 0001 NE R3 R0 R3 + 0x780E0007, // 0002 JMPF R3 #000B + 0x8C0C0500, // 0003 GETMET R3 R2 K0 + 0x5C140000, // 0004 MOVE R5 R0 + 0x7C0C0400, // 0005 CALL R3 2 + 0x4C100000, // 0006 LDNIL R4 + 0x200C0604, // 0007 NE R3 R3 R4 + 0x780E0001, // 0008 JMPF R3 #000B + 0x80040000, // 0009 RET 1 R0 + 0x70020000, // 000A JMP #000C + 0x80040200, // 000B RET 1 R1 + 0x80000000, // 000C RET 0 + }) + ), + }), 1, /* has constants */ &be_ktab_class_HASPmota, /* shared constants */ be_str_weak(page_show), &be_const_str_solidified, - ( &(const binstruction[71]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x880C010B, // 0001 GETMBR R3 R0 K11 - 0x8810010C, // 0002 GETMBR R4 R0 K12 - 0x940C0604, // 0003 GETIDX R3 R3 R4 - 0x8C10013E, // 0004 GETMET R4 R0 K62 - 0x8818010C, // 0005 GETMBR R6 R0 K12 - 0x7C100400, // 0006 CALL R4 2 - 0x6014000C, // 0007 GETGBL R5 G12 - 0x5C180800, // 0008 MOVE R6 R4 - 0x7C140200, // 0009 CALL R5 1 - 0x18140B15, // 000A LE R5 R5 K21 - 0x78160000, // 000B JMPF R5 #000D - 0x80000A00, // 000C RET 0 - 0x1C140321, // 000D EQ R5 R1 K33 - 0x78160009, // 000E JMPF R5 #0019 - 0x60140009, // 000F GETGBL R5 G9 - 0x88180721, // 0010 GETMBR R6 R3 K33 - 0x7C140200, // 0011 CALL R5 1 - 0x5C080A00, // 0012 MOVE R2 R5 - 0x4C140000, // 0013 LDNIL R5 - 0x1C140405, // 0014 EQ R5 R2 R5 - 0x78160001, // 0015 JMPF R5 #0018 - 0x5415FFFE, // 0016 LDINT R5 -1 - 0x94080805, // 0017 GETIDX R2 R4 R5 - 0x70020023, // 0018 JMP #003D - 0x1C140322, // 0019 EQ R5 R1 K34 - 0x78160008, // 001A JMPF R5 #0024 - 0x60140009, // 001B GETGBL R5 G9 - 0x88180722, // 001C GETMBR R6 R3 K34 - 0x7C140200, // 001D CALL R5 1 - 0x5C080A00, // 001E MOVE R2 R5 - 0x4C140000, // 001F LDNIL R5 - 0x1C140405, // 0020 EQ R5 R2 R5 - 0x78160000, // 0021 JMPF R5 #0023 - 0x94080915, // 0022 GETIDX R2 R4 K21 - 0x70020018, // 0023 JMP #003D - 0x1C140323, // 0024 EQ R5 R1 K35 - 0x7816000B, // 0025 JMPF R5 #0032 - 0x60140009, // 0026 GETGBL R5 G9 - 0x88180723, // 0027 GETMBR R6 R3 K35 - 0x7C140200, // 0028 CALL R5 1 - 0x5C080A00, // 0029 MOVE R2 R5 - 0x4C140000, // 002A LDNIL R5 - 0x1C140405, // 002B EQ R5 R2 R5 - 0x78160003, // 002C JMPF R5 #0031 - 0x8C14013E, // 002D GETMET R5 R0 K62 - 0x4C1C0000, // 002E LDNIL R7 - 0x7C140400, // 002F CALL R5 2 - 0x94080B0F, // 0030 GETIDX R2 R5 K15 - 0x7002000A, // 0031 JMP #003D - 0x88140118, // 0032 GETMBR R5 R0 K24 - 0x8C140B41, // 0033 GETMET R5 R5 K65 - 0x5C1C0200, // 0034 MOVE R7 R1 - 0x7C140400, // 0035 CALL R5 2 - 0x78160005, // 0036 JMPF R5 #003D - 0x60140009, // 0037 GETGBL R5 G9 - 0x5419FFFE, // 0038 LDINT R6 -1 - 0x401A2A06, // 0039 CONNECT R6 K21 R6 - 0x94180206, // 003A GETIDX R6 R1 R6 - 0x7C140200, // 003B CALL R5 1 - 0x5C080A00, // 003C MOVE R2 R5 - 0x4C140000, // 003D LDNIL R5 - 0x20140405, // 003E NE R5 R2 R5 - 0x78160005, // 003F JMPF R5 #0046 - 0x2414050F, // 0040 GT R5 R2 K15 - 0x78160003, // 0041 JMPF R5 #0046 - 0x8814010B, // 0042 GETMBR R5 R0 K11 - 0x94140A02, // 0043 GETIDX R5 R5 R2 - 0x8C140B40, // 0044 GETMET R5 R5 K64 - 0x7C140200, // 0045 CALL R5 1 - 0x80000000, // 0046 RET 0 + ( &(const binstruction[108]) { /* code */ + 0x84100000, // 0000 CLOSURE R4 P0 + 0x4C140000, // 0001 LDNIL R5 + 0x8C180120, // 0002 GETMET R6 R0 K32 + 0x7C180200, // 0003 CALL R6 1 + 0x8C1C013E, // 0004 GETMET R7 R0 K62 + 0x8824010C, // 0005 GETMBR R9 R0 K12 + 0x7C1C0400, // 0006 CALL R7 2 + 0x6020000C, // 0007 GETGBL R8 G12 + 0x5C240E00, // 0008 MOVE R9 R7 + 0x7C200200, // 0009 CALL R8 1 + 0x18201115, // 000A LE R8 R8 K21 + 0x78220001, // 000B JMPF R8 #000E + 0x4C200000, // 000C LDNIL R8 + 0x80041000, // 000D RET 1 R8 + 0x1C200321, // 000E EQ R8 R1 K33 + 0x78220009, // 000F JMPF R8 #001A + 0x5C200800, // 0010 MOVE R8 R4 + 0x60240009, // 0011 GETGBL R9 G9 + 0x88280D21, // 0012 GETMBR R10 R6 K33 + 0x7C240200, // 0013 CALL R9 1 + 0x5429FFFE, // 0014 LDINT R10 -1 + 0x94280E0A, // 0015 GETIDX R10 R7 R10 + 0x5C2C0E00, // 0016 MOVE R11 R7 + 0x7C200600, // 0017 CALL R8 3 + 0x5C141000, // 0018 MOVE R5 R8 + 0x70020041, // 0019 JMP #005C + 0x1C200322, // 001A EQ R8 R1 K34 + 0x78220008, // 001B JMPF R8 #0025 + 0x5C200800, // 001C MOVE R8 R4 + 0x60240009, // 001D GETGBL R9 G9 + 0x88280D22, // 001E GETMBR R10 R6 K34 + 0x7C240200, // 001F CALL R9 1 + 0x94280F15, // 0020 GETIDX R10 R7 K21 + 0x5C2C0E00, // 0021 MOVE R11 R7 + 0x7C200600, // 0022 CALL R8 3 + 0x5C141000, // 0023 MOVE R5 R8 + 0x70020036, // 0024 JMP #005C + 0x1C200323, // 0025 EQ R8 R1 K35 + 0x7822000B, // 0026 JMPF R8 #0033 + 0x5C200800, // 0027 MOVE R8 R4 + 0x60240009, // 0028 GETGBL R9 G9 + 0x88280D23, // 0029 GETMBR R10 R6 K35 + 0x7C240200, // 002A CALL R9 1 + 0x8C28013E, // 002B GETMET R10 R0 K62 + 0x4C300000, // 002C LDNIL R12 + 0x7C280400, // 002D CALL R10 2 + 0x9428150F, // 002E GETIDX R10 R10 K15 + 0x5C2C0E00, // 002F MOVE R11 R7 + 0x7C200600, // 0030 CALL R8 3 + 0x5C141000, // 0031 MOVE R5 R8 + 0x70020028, // 0032 JMP #005C + 0x1C200341, // 0033 EQ R8 R1 K65 + 0x78220017, // 0034 JMPF R8 #004D + 0x5C200800, // 0035 MOVE R8 R4 + 0x60240009, // 0036 GETGBL R9 G9 + 0x88280D23, // 0037 GETMBR R10 R6 K35 + 0x7C240200, // 0038 CALL R9 1 + 0x8C28013E, // 0039 GETMET R10 R0 K62 + 0x4C300000, // 003A LDNIL R12 + 0x7C280400, // 003B CALL R10 2 + 0x9428150F, // 003C GETIDX R10 R10 K15 + 0x5C2C0E00, // 003D MOVE R11 R7 + 0x7C200600, // 003E CALL R8 3 + 0x5C141000, // 003F MOVE R5 R8 + 0x8C200D1F, // 0040 GETMET R8 R6 K31 + 0x7C200200, // 0041 CALL R8 1 + 0x1C200A08, // 0042 EQ R8 R5 R8 + 0x78220007, // 0043 JMPF R8 #004C + 0x5C200800, // 0044 MOVE R8 R4 + 0x60240009, // 0045 GETGBL R9 G9 + 0x88280D22, // 0046 GETMBR R10 R6 K34 + 0x7C240200, // 0047 CALL R9 1 + 0x94280F15, // 0048 GETIDX R10 R7 K21 + 0x5C2C0E00, // 0049 MOVE R11 R7 + 0x7C200600, // 004A CALL R8 3 + 0x5C141000, // 004B MOVE R5 R8 + 0x7002000E, // 004C JMP #005C + 0x88200118, // 004D GETMBR R8 R0 K24 + 0x8C201142, // 004E GETMET R8 R8 K66 + 0x5C280200, // 004F MOVE R10 R1 + 0x7C200400, // 0050 CALL R8 2 + 0x78220009, // 0051 JMPF R8 #005C + 0x5C200800, // 0052 MOVE R8 R4 + 0x60240009, // 0053 GETGBL R9 G9 + 0x5429FFFE, // 0054 LDINT R10 -1 + 0x402A2A0A, // 0055 CONNECT R10 K21 R10 + 0x9428020A, // 0056 GETIDX R10 R1 R10 + 0x7C240200, // 0057 CALL R9 1 + 0x4C280000, // 0058 LDNIL R10 + 0x5C2C0E00, // 0059 MOVE R11 R7 + 0x7C200600, // 005A CALL R8 3 + 0x5C141000, // 005B MOVE R5 R8 + 0x4C200000, // 005C LDNIL R8 + 0x20200A08, // 005D NE R8 R5 R8 + 0x7822000B, // 005E JMPF R8 #006B + 0x24200B0F, // 005F GT R8 R5 K15 + 0x78220009, // 0060 JMPF R8 #006B + 0x8820010B, // 0061 GETMBR R8 R0 K11 + 0x94201005, // 0062 GETIDX R8 R8 R5 + 0x4C240000, // 0063 LDNIL R9 + 0x20241009, // 0064 NE R9 R8 R9 + 0x78260003, // 0065 JMPF R9 #006A + 0x8C241140, // 0066 GETMET R9 R8 K64 + 0x5C2C0400, // 0067 MOVE R11 R2 + 0x5C300600, // 0068 MOVE R12 R3 + 0x7C240600, // 0069 CALL R9 3 + 0x80041000, // 006A RET 1 R8 + 0x80000000, // 006B RET 0 }) ) ); @@ -11542,108 +11804,108 @@ be_local_closure(class_HASPmota_start, /* name */ be_str_weak(start), &be_const_str_solidified, ( &(const binstruction[105]) { /* code */ - 0xA40E8400, // 0000 IMPORT R3 K66 + 0xA40E8600, // 0000 IMPORT R3 K67 0x4C100000, // 0001 LDNIL R4 0x1C100404, // 0002 EQ R4 R2 R4 0x78120000, // 0003 JMPF R4 #0005 - 0x88080143, // 0004 GETMBR R2 R0 K67 - 0x8C100744, // 0005 GETMET R4 R3 K68 + 0x88080144, // 0004 GETMBR R2 R0 K68 + 0x8C100745, // 0005 GETMET R4 R3 K69 0x5C180400, // 0006 MOVE R6 R2 0x7C100400, // 0007 CALL R4 2 0x74120002, // 0008 JMPT R4 #000C - 0x00128A02, // 0009 ADD R4 K69 R2 - 0x00100946, // 000A ADD R4 R4 K70 - 0xB0068E04, // 000B RAISE 1 K71 R4 + 0x00128C02, // 0009 ADD R4 K70 R2 + 0x00100947, // 000A ADD R4 R4 K71 + 0xB0069004, // 000B RAISE 1 K72 R4 0xB8120600, // 000C GETNGBL R4 K3 - 0x8C100948, // 000D GETMET R4 R4 K72 + 0x8C100949, // 000D GETMET R4 R4 K73 0x7C100200, // 000E CALL R4 1 0x60100017, // 000F GETGBL R4 G23 0x5C140200, // 0010 MOVE R5 R1 0x7C100200, // 0011 CALL R4 1 - 0x90029204, // 0012 SETMBR R0 K73 R4 + 0x90029404, // 0012 SETMBR R0 K74 R4 0xB8120600, // 0013 GETNGBL R4 K3 - 0x8C10094B, // 0014 GETMET R4 R4 K75 + 0x8C10094C, // 0014 GETMET R4 R4 K76 0x7C100200, // 0015 CALL R4 1 - 0x90029404, // 0016 SETMBR R0 K74 R4 + 0x90029604, // 0016 SETMBR R0 K75 R4 0xB8120600, // 0017 GETNGBL R4 K3 - 0x8C10094D, // 0018 GETMET R4 R4 K77 + 0x8C10094E, // 0018 GETMET R4 R4 K78 0x7C100200, // 0019 CALL R4 1 - 0x90029804, // 001A SETMBR R0 K76 R4 + 0x90029A04, // 001A SETMBR R0 K77 R4 0xB8120600, // 001B GETNGBL R4 K3 - 0x8C10094F, // 001C GETMET R4 R4 K79 + 0x8C100950, // 001C GETMET R4 R4 K80 0x7C100200, // 001D CALL R4 1 - 0x90029C04, // 001E SETMBR R0 K78 R4 + 0x90029E04, // 001E SETMBR R0 K79 R4 0xA8020007, // 001F EXBLK 0 #0028 0xB8120600, // 0020 GETNGBL R4 K3 - 0x8C100951, // 0021 GETMET R4 R4 K81 - 0x58180052, // 0022 LDCONST R6 K82 + 0x8C100952, // 0021 GETMET R4 R4 K82 + 0x58180053, // 0022 LDCONST R6 K83 0x541E000F, // 0023 LDINT R7 16 0x7C100600, // 0024 CALL R4 3 - 0x9002A004, // 0025 SETMBR R0 K80 R4 + 0x9002A204, // 0025 SETMBR R0 K81 R4 0xA8040001, // 0026 EXBLK 1 1 0x70020009, // 0027 JMP #0032 0xAC100000, // 0028 CATCH R4 0 0 0x70020006, // 0029 JMP #0031 0xB8120600, // 002A GETNGBL R4 K3 - 0x8C100951, // 002B GETMET R4 R4 K81 - 0x58180053, // 002C LDCONST R6 K83 + 0x8C100952, // 002B GETMET R4 R4 K82 + 0x58180054, // 002C LDCONST R6 K84 0x541E000D, // 002D LDINT R7 14 0x7C100600, // 002E CALL R4 3 - 0x9002A004, // 002F SETMBR R0 K80 R4 + 0x9002A204, // 002F SETMBR R0 K81 R4 0x70020000, // 0030 JMP #0032 0xB0080000, // 0031 RAISE 2 R0 R0 0xB8120600, // 0032 GETNGBL R4 K3 - 0x8C100954, // 0033 GETMET R4 R4 K84 + 0x8C100955, // 0033 GETMET R4 R4 K85 0x5818000F, // 0034 LDCONST R6 K15 0xB81E0600, // 0035 GETNGBL R7 K3 - 0x8C1C0F55, // 0036 GETMET R7 R7 K85 - 0x58240056, // 0037 LDCONST R9 K86 + 0x8C1C0F56, // 0036 GETMET R7 R7 K86 + 0x58240057, // 0037 LDCONST R9 K87 0x7C1C0400, // 0038 CALL R7 2 0xB8220600, // 0039 GETNGBL R8 K3 - 0x8C201155, // 003A GETMET R8 R8 K85 - 0x58280057, // 003B LDCONST R10 K87 + 0x8C201156, // 003A GETMET R8 R8 K86 + 0x58280058, // 003B LDCONST R10 K88 0x7C200400, // 003C CALL R8 2 - 0x88240149, // 003D GETMBR R9 R0 K73 - 0x88280150, // 003E GETMBR R10 R0 K80 + 0x8824014A, // 003D GETMBR R9 R0 K74 + 0x88280151, // 003E GETMBR R10 R0 K81 0x7C100C00, // 003F CALL R4 6 - 0x8814014E, // 0040 GETMBR R5 R0 K78 - 0x8C140B58, // 0041 GETMET R5 R5 K88 + 0x8814014F, // 0040 GETMBR R5 R0 K79 + 0x8C140B59, // 0041 GETMET R5 R5 K89 0x7C140200, // 0042 CALL R5 1 - 0x8C140B59, // 0043 GETMET R5 R5 K89 + 0x8C140B5A, // 0043 GETMET R5 R5 K90 0x5C1C0800, // 0044 MOVE R7 R4 0x7C140400, // 0045 CALL R5 2 - 0x8814014E, // 0046 GETMBR R5 R0 K78 - 0x8C140B5A, // 0047 GETMET R5 R5 K90 - 0x881C0149, // 0048 GETMBR R7 R0 K73 + 0x8814014F, // 0046 GETMBR R5 R0 K79 + 0x8C140B5B, // 0047 GETMET R5 R5 K91 + 0x881C014A, // 0048 GETMBR R7 R0 K74 0x781E0004, // 0049 JMPF R7 #004F 0xB81E0600, // 004A GETNGBL R7 K3 - 0x8C1C0F55, // 004B GETMET R7 R7 K85 + 0x8C1C0F56, // 004B GETMET R7 R7 K86 0x5824000F, // 004C LDCONST R9 K15 0x7C1C0400, // 004D CALL R7 2 0x70020003, // 004E JMP #0053 0xB81E0600, // 004F GETNGBL R7 K3 - 0x8C1C0F55, // 0050 GETMET R7 R7 K85 - 0x5824005B, // 0051 LDCONST R9 K91 + 0x8C1C0F56, // 0050 GETMET R7 R7 K86 + 0x5824005C, // 0051 LDCONST R9 K92 0x7C1C0400, // 0052 CALL R7 2 0x5820000F, // 0053 LDCONST R8 K15 0x7C140600, // 0054 CALL R5 3 0xB8160600, // 0055 GETNGBL R5 K3 - 0x8C140B5C, // 0056 GETMET R5 R5 K92 + 0x8C140B5D, // 0056 GETMET R5 R5 K93 0xB81E0600, // 0057 GETNGBL R7 K3 - 0x8C1C0F5D, // 0058 GETMET R7 R7 K93 + 0x8C1C0F5E, // 0058 GETMET R7 R7 K94 0x7C1C0200, // 0059 CALL R7 1 0x7C140400, // 005A CALL R5 2 0xB8160600, // 005B GETNGBL R5 K3 - 0x8C140B5D, // 005C GETMET R5 R5 K93 + 0x8C140B5E, // 005C GETMET R5 R5 K94 0x7C140200, // 005D CALL R5 1 - 0x8C140B5E, // 005E GETMET R5 R5 K94 + 0x8C140B5F, // 005E GETMET R5 R5 K95 0x581C000F, // 005F LDCONST R7 K15 0x5820000F, // 0060 LDCONST R8 K15 0x7C140600, // 0061 CALL R5 3 0x60140013, // 0062 GETGBL R5 G19 0x7C140000, // 0063 CALL R5 0 0x90021605, // 0064 SETMBR R0 K11 R5 - 0x8C14015F, // 0065 GETMET R5 R0 K95 + 0x8C140160, // 0065 GETMET R5 R0 K96 0x5C1C0400, // 0066 MOVE R7 R2 0x7C140400, // 0067 CALL R5 2 0x80000000, // 0068 RET 0 @@ -11658,7 +11920,7 @@ be_local_closure(class_HASPmota_start, /* name */ ********************************************************************/ be_local_closure(class_HASPmota__remove_page, /* name */ be_nested_proto( - 5, /* nstack */ + 8, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -11669,17 +11931,39 @@ be_local_closure(class_HASPmota__remove_page, /* name */ &be_ktab_class_HASPmota, /* shared constants */ be_str_weak(_remove_page), &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x8808010B, // 0000 GETMBR R2 R0 K11 - 0x8C08051D, // 0001 GETMET R2 R2 K29 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x780A0003, // 0004 JMPF R2 #0009 - 0x8808010B, // 0005 GETMBR R2 R0 K11 - 0x8C08053D, // 0006 GETMET R2 R2 K61 - 0x5C100200, // 0007 MOVE R4 R1 - 0x7C080400, // 0008 CALL R2 2 - 0x80000000, // 0009 RET 0 + ( &(const binstruction[32]) { /* code */ + 0x8C080120, // 0000 GETMET R2 R0 K32 + 0x7C080200, // 0001 CALL R2 1 + 0x8C08051F, // 0002 GETMET R2 R2 K31 + 0x7C080200, // 0003 CALL R2 1 + 0x1C0C0202, // 0004 EQ R3 R1 R2 + 0x780E0008, // 0005 JMPF R3 #000F + 0x8C0C0125, // 0006 GETMET R3 R0 K37 + 0x58140041, // 0007 LDCONST R5 K65 + 0x5818000F, // 0008 LDCONST R6 K15 + 0x581C000F, // 0009 LDCONST R7 K15 + 0x7C0C0800, // 000A CALL R3 4 + 0x4C100000, // 000B LDNIL R4 + 0x1C100604, // 000C EQ R4 R3 R4 + 0x78120000, // 000D JMPF R4 #000F + 0x80000800, // 000E RET 0 + 0x880C010B, // 000F GETMBR R3 R0 K11 + 0x8C0C071D, // 0010 GETMET R3 R3 K29 + 0x5C140200, // 0011 MOVE R5 R1 + 0x7C0C0400, // 0012 CALL R3 2 + 0x780E0003, // 0013 JMPF R3 #0018 + 0x880C010B, // 0014 GETMBR R3 R0 K11 + 0x8C0C073D, // 0015 GETMET R3 R3 K61 + 0x5C140200, // 0016 MOVE R5 R1 + 0x7C0C0400, // 0017 CALL R3 2 + 0x600C0018, // 0018 GETGBL R3 G24 + 0x58100062, // 0019 LDCONST R4 K98 + 0x5C140200, // 001A MOVE R5 R1 + 0x7C0C0400, // 001B CALL R3 2 + 0xB812C200, // 001C GETNGBL R4 K97 + 0x4C140000, // 001D LDNIL R5 + 0x90100605, // 001E SETMBR R4 R3 R5 + 0x80000000, // 001F RET 0 }) ) ); @@ -11756,7 +12040,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ be_str_weak(parse_obj), &be_const_str_solidified, ( &(const binstruction[239]) { /* code */ - 0xA40EC000, // 0000 IMPORT R3 K96 + 0xA40EC200, // 0000 IMPORT R3 K97 0xA4120200, // 0001 IMPORT R4 K1 0x60140009, // 0002 GETGBL R5 G9 0x8C180314, // 0003 GETMET R6 R1 K20 @@ -11764,7 +12048,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x7C180400, // 0005 CALL R6 2 0x7C140200, // 0006 CALL R5 1 0x8C180314, // 0007 GETMET R6 R1 K20 - 0x58200061, // 0008 LDCONST R8 K97 + 0x58200063, // 0008 LDCONST R8 K99 0x7C180400, // 0009 CALL R6 2 0x4C1C0000, // 000A LDNIL R7 0x201C0C07, // 000B NE R7 R6 R7 @@ -11792,13 +12076,13 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x78220007, // 0021 JMPF R8 #002A 0x60200001, // 0022 GETGBL R8 G1 0x60240018, // 0023 GETGBL R9 G24 - 0x58280062, // 0024 LDCONST R10 K98 + 0x58280064, // 0024 LDCONST R10 K100 0x5C2C0A00, // 0025 MOVE R11 R5 0x5C300C00, // 0026 MOVE R12 R6 0x7C240600, // 0027 CALL R9 3 0x7C200200, // 0028 CALL R8 1 0x80001000, // 0029 RET 0 - 0x8C200F63, // 002A GETMET R8 R7 K99 + 0x8C200F65, // 002A GETMET R8 R7 K101 0x5C280A00, // 002B MOVE R10 R5 0x7C200400, // 002C CALL R8 2 0x4C240000, // 002D LDNIL R9 @@ -11812,7 +12096,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x78260059, // 0035 JMPF R9 #0090 0x60240009, // 0036 GETGBL R9 G9 0x8C280314, // 0037 GETMET R10 R1 K20 - 0x58300064, // 0038 LDCONST R12 K100 + 0x58300066, // 0038 LDCONST R12 K102 0x7C280400, // 0039 CALL R10 2 0x7C240200, // 003A CALL R9 1 0x4C280000, // 003B LDNIL R10 @@ -11820,7 +12104,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x4C300000, // 003D LDNIL R12 0x2030120C, // 003E NE R12 R9 R12 0x78320007, // 003F JMPF R12 #0048 - 0x8C300F63, // 0040 GETMET R12 R7 K99 + 0x8C300F65, // 0040 GETMET R12 R7 K101 0x5C381200, // 0041 MOVE R14 R9 0x7C300400, // 0042 CALL R12 2 0x5C281800, // 0043 MOVE R10 R12 @@ -11831,12 +12115,12 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x4C300000, // 0048 LDNIL R12 0x1C30160C, // 0049 EQ R12 R11 R12 0x78320002, // 004A JMPF R12 #004E - 0x8C300F65, // 004B GETMET R12 R7 K101 + 0x8C300F67, // 004B GETMET R12 R7 K103 0x7C300200, // 004C CALL R12 1 0x5C2C1800, // 004D MOVE R11 R12 0x8C300902, // 004E GETMET R12 R4 K2 0x5C380000, // 004F MOVE R14 R0 - 0x003ECC06, // 0050 ADD R15 K102 R6 + 0x003ED006, // 0050 ADD R15 K104 R6 0x7C300600, // 0051 CALL R12 3 0x4C340000, // 0052 LDNIL R13 0x4C380000, // 0053 LDNIL R14 @@ -11852,17 +12136,17 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x603C0004, // 005D GETGBL R15 G4 0x5C401C00, // 005E MOVE R16 R14 0x7C3C0200, // 005F CALL R15 1 - 0x1C3C1F67, // 0060 EQ R15 R15 K103 + 0x1C3C1F69, // 0060 EQ R15 R15 K105 0x783E0004, // 0061 JMPF R15 #0067 0x5C3C1C00, // 0062 MOVE R15 R14 0x5C401600, // 0063 MOVE R16 R11 0x7C3C0200, // 0064 CALL R15 1 0x5C341E00, // 0065 MOVE R13 R15 - 0x88300168, // 0066 GETMBR R12 R0 K104 + 0x8830016A, // 0066 GETMBR R12 R0 K106 0x4C380000, // 0067 LDNIL R14 0x1C38180E, // 0068 EQ R14 R12 R14 0x783A000F, // 0069 JMPF R14 #007A - 0x8C380969, // 006A GETMET R14 R4 K105 + 0x8C38096B, // 006A GETMET R14 R4 K107 0x5C400C00, // 006B MOVE R16 R6 0x7C380400, // 006C CALL R14 2 0x4C3C0000, // 006D LDNIL R15 @@ -11871,19 +12155,19 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x603C0004, // 0070 GETGBL R15 G4 0x5C401C00, // 0071 MOVE R16 R14 0x7C3C0200, // 0072 CALL R15 1 - 0x1C3C1F67, // 0073 EQ R15 R15 K103 + 0x1C3C1F69, // 0073 EQ R15 R15 K105 0x783E0004, // 0074 JMPF R15 #007A 0x5C3C1C00, // 0075 MOVE R15 R14 0x5C401600, // 0076 MOVE R16 R11 0x7C3C0200, // 0077 CALL R15 1 0x5C341E00, // 0078 MOVE R13 R15 - 0x88300168, // 0079 GETMBR R12 R0 K104 + 0x8830016A, // 0079 GETMBR R12 R0 K106 0x4C380000, // 007A LDNIL R14 0x1C38180E, // 007B EQ R14 R12 R14 0x783A0006, // 007C JMPF R14 #0084 0x60380001, // 007D GETGBL R14 G1 0x603C0018, // 007E GETGBL R15 G24 - 0x5840006A, // 007F LDCONST R16 K106 + 0x5840006C, // 007F LDCONST R16 K108 0x5C440C00, // 0080 MOVE R17 R6 0x7C3C0400, // 0081 CALL R15 2 0x7C380200, // 0082 CALL R14 1 @@ -11896,7 +12180,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x5C4C1400, // 0089 MOVE R19 R10 0x7C380A00, // 008A CALL R14 5 0x5C201C00, // 008B MOVE R8 R14 - 0x8C380F6B, // 008C GETMET R14 R7 K107 + 0x8C380F6D, // 008C GETMET R14 R7 K109 0x5C400A00, // 008D MOVE R16 R5 0x5C441000, // 008E MOVE R17 R8 0x7C380600, // 008F CALL R14 3 @@ -11907,14 +12191,14 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x78260006, // 0094 JMPF R9 #009C 0x60240001, // 0095 GETGBL R9 G1 0x60280018, // 0096 GETGBL R10 G24 - 0x582C006C, // 0097 LDCONST R11 K108 + 0x582C006E, // 0097 LDCONST R11 K110 0x5C300C00, // 0098 MOVE R12 R6 0x7C280400, // 0099 CALL R10 2 0x7C240200, // 009A CALL R9 1 0x80001200, // 009B RET 0 0x8C240120, // 009C GETMET R9 R0 K32 0x7C240200, // 009D CALL R9 1 - 0x8C241363, // 009E GETMET R9 R9 K99 + 0x8C241365, // 009E GETMET R9 R9 K101 0x582C000F, // 009F LDCONST R11 K15 0x7C240400, // 00A0 CALL R9 2 0x5C201200, // 00A1 MOVE R8 R9 @@ -11937,15 +12221,15 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x4C240000, // 00B2 LDNIL R9 0x20241009, // 00B3 NE R9 R8 R9 0x78260001, // 00B4 JMPF R9 #00B7 - 0x8C24116D, // 00B5 GETMET R9 R8 K109 + 0x8C24116F, // 00B5 GETMET R9 R8 K111 0x7C240200, // 00B6 CALL R9 1 0x4C240000, // 00B7 LDNIL R9 0x60280008, // 00B8 GETGBL R10 G8 0x8C2C0314, // 00B9 GETMET R11 R1 K20 - 0x5834006E, // 00BA LDCONST R13 K110 + 0x58340070, // 00BA LDCONST R13 K112 0x7C2C0400, // 00BB CALL R11 2 0x7C280200, // 00BC CALL R10 1 - 0x202C156F, // 00BD NE R11 R10 K111 + 0x202C1571, // 00BD NE R11 R10 K113 0x782E0012, // 00BE JMPF R11 #00D2 0xA8020005, // 00BF EXBLK 0 #00C6 0x602C000D, // 00C0 GETGBL R11 G13 @@ -11958,7 +12242,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x70020008, // 00C7 JMP #00D1 0x60340001, // 00C8 GETGBL R13 G1 0x60380018, // 00C9 GETGBL R14 G24 - 0x583C0070, // 00CA LDCONST R15 K112 + 0x583C0072, // 00CA LDCONST R15 K114 0x5C401400, // 00CB MOVE R16 R10 0x5C441600, // 00CC MOVE R17 R11 0x5C481800, // 00CD MOVE R18 R12 @@ -11975,7 +12259,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x60300004, // 00D8 GETGBL R12 G4 0x5C341600, // 00D9 MOVE R13 R11 0x7C300200, // 00DA CALL R12 1 - 0x1C301971, // 00DB EQ R12 R12 K113 + 0x1C301973, // 00DB EQ R12 R12 K115 0x78320002, // 00DC JMPF R12 #00E0 0x5C301600, // 00DD MOVE R12 R11 0x5C341000, // 00DE MOVE R13 R8 @@ -11986,7 +12270,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x70020008, // 00E3 JMP #00ED 0x60340001, // 00E4 GETGBL R13 G1 0x60380018, // 00E5 GETGBL R14 G24 - 0x583C0072, // 00E6 LDCONST R15 K114 + 0x583C0074, // 00E6 LDCONST R15 K116 0x5C401400, // 00E7 MOVE R16 R10 0x5C441600, // 00E8 MOVE R17 R11 0x5C481800, // 00E9 MOVE R18 R12 @@ -12022,25 +12306,25 @@ be_local_closure(class_HASPmota_event_dispatch, /* name */ 0x8C0C052C, // 0001 GETMET R3 R2 K44 0x5C140200, // 0002 MOVE R5 R1 0x7C0C0400, // 0003 CALL R3 2 - 0x88100173, // 0004 GETMBR R4 R0 K115 + 0x88100175, // 0004 GETMBR R4 R0 K117 0x78120002, // 0005 JMPF R4 #0009 - 0x88100173, // 0006 GETMBR R4 R0 K115 - 0x9012E803, // 0007 SETMBR R4 K116 R3 + 0x88100175, // 0006 GETMBR R4 R0 K117 + 0x9012EC03, // 0007 SETMBR R4 K118 R3 0x70020004, // 0008 JMP #000E 0xB8120600, // 0009 GETNGBL R4 K3 - 0x8C100975, // 000A GETMET R4 R4 K117 + 0x8C100977, // 000A GETMET R4 R4 K119 0x5C180600, // 000B MOVE R6 R3 0x7C100400, // 000C CALL R4 2 - 0x9002E604, // 000D SETMBR R0 K115 R4 - 0x88100173, // 000E GETMBR R4 R0 K115 - 0x8C100976, // 000F GETMET R4 R4 K118 + 0x9002EA04, // 000D SETMBR R0 K117 R4 + 0x88100175, // 000E GETMBR R4 R0 K117 + 0x8C100978, // 000F GETMET R4 R4 K120 0x7C100200, // 0010 CALL R4 1 0x60140009, // 0011 GETGBL R5 G9 0x5C180800, // 0012 MOVE R6 R4 0x7C140200, // 0013 CALL R5 1 0x20140B0F, // 0014 NE R5 R5 K15 0x7816000A, // 0015 JMPF R5 #0021 - 0x8C140577, // 0016 GETMET R5 R2 K119 + 0x8C140579, // 0016 GETMET R5 R2 K121 0x5C1C0800, // 0017 MOVE R7 R4 0x7C140400, // 0018 CALL R5 2 0x60180004, // 0019 GETGBL R6 G4 @@ -12049,7 +12333,7 @@ be_local_closure(class_HASPmota_event_dispatch, /* name */ 0x1C180D08, // 001C EQ R6 R6 K8 0x781A0002, // 001D JMPF R6 #0021 0x8C180B28, // 001E GETMET R6 R5 K40 - 0x88200173, // 001F GETMBR R8 R0 K115 + 0x88200175, // 001F GETMBR R8 R0 K117 0x7C180400, // 0020 CALL R6 2 0x80000000, // 0021 RET 0 }) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino index abbeea257..ad7029310 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino @@ -374,7 +374,7 @@ void start_lvgl(const char * uconfig); void start_lvgl(const char * uconfig) { if (lvgl_glue != nullptr) { - AddLog(LOG_LEVEL_DEBUG, D_LOG_LVGL "LVGL was already initialized"); + AddLog(LOG_LEVEL_DEBUG_MORE, D_LOG_LVGL "LVGL was already initialized"); return; } From 148f8350b622dca3093151476040ae35d538d92c Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Sat, 19 Oct 2024 11:30:58 +0200 Subject: [PATCH 019/205] HASPmota fix current page parsing (#22320) --- .../lv_haspmota/src/embedded/lv_haspmota.be | 32 +- .../src/solidify/solidified_lv_haspmota.h | 2103 +++++++++-------- 2 files changed, 1096 insertions(+), 1039 deletions(-) diff --git a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be index 93b6acbd2..31cf11e98 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be +++ b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be @@ -2545,6 +2545,7 @@ class HASPmota # haspmota objects var lvh_pages # (list of lvg_page) list of pages var lvh_page_cur_idx # (int) current page index number + var lvh_page_cur_idx_parsing # (int) index of the current page related to parsing JSONL, can be different from the displayed page # regex patterns var re_page_target # compiled regex for action `p` # specific event_cb handling for less memory usage since we are registering a lot of callbacks @@ -2677,6 +2678,12 @@ class HASPmota def get_page_cur() return self.lvh_pages[self.lvh_page_cur_idx] end + #==================================================================== + # return the current page being parsed with JSONL as `lvh_page` object + #==================================================================== + def get_page_cur_parsing() + return self.lvh_pages[self.lvh_page_cur_idx_parsing] + end #==================================================================== # load JSONL template @@ -2701,12 +2708,12 @@ class HASPmota if tasmota.loglevel(4) tasmota.log(f"HSP: parsing line '{jsonl[0]}'", 4) end - self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx + self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx_parsing # objects are created in the current page if (self.lvh_pages == nil) raise "value_error", "no page 'id' defined" end - self.parse_obj(jline, self.lvh_pages[self.lvh_page_cur_idx]) # then parse object within this page + self.parse_obj(jline, self.lvh_pages[self.lvh_page_cur_idx_parsing]) # then parse object within this page else # check if it's invalid json if size(string.tr(jsonl[0], " \t", "")) > 0 @@ -2737,7 +2744,7 @@ class HASPmota var jline = json.load(j) if type(jline) == 'instance' - self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx + self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx_parsing # objects are created in the current page self.parse_obj(jline, self.lvh_pages[self.lvh_page_cur_idx]) # then parse object within this page else @@ -2871,9 +2878,10 @@ class HASPmota to_page = to_page_resolve(int(action[1..-1]), nil #-default to nil-#, sorted_pages_list) end - # print("to_page=",to_page) + # print(f"{action=} {to_page=}") if (to_page != nil) && (to_page > 0) # we have a target var to_page_obj = self.lvh_pages[to_page] + # print(f"{to_page_obj.id()=}") if (to_page_obj != nil) to_page_obj.show(anim, duration) end @@ -2890,7 +2898,11 @@ class HASPmota def parse_page(jline) if jline.has("page") && type(jline["page"]) == 'int' var page = int(jline["page"]) - self.lvh_page_cur_idx = page # change current page + # print(f">>> parsing page {page}") + self.lvh_page_cur_idx_parsing = page # change current page + if (self.lvh_page_cur_idx == nil) # also set current page if we haven't any yet + self.lvh_page_cur_idx = page + end # create the page object if it doesn't exist already if !self.lvh_pages.contains(page) @@ -2900,7 +2912,7 @@ class HASPmota # check if there is "id":0 if jline.find("id") == 0 - var lvh_page_cur = self.get_page_cur() + var lvh_page_cur = self.get_page_cur_parsing() lvh_page_cur.prev = int(jline.find("prev", nil)) lvh_page_cur.next = int(jline.find("next", nil)) lvh_page_cur.back = int(jline.find("back", nil)) @@ -2926,6 +2938,10 @@ class HASPmota return end end + # also update lvh_page_cur_idx_parsing, if we removed the current parsing page + if (self.lvh_page_cur_idx_parsing == page_id) + self.lvh_page_cur_idx_parsing = self.lvh_page_cur_idx + end # remove object from page object if self.lvh_pages.contains(page_id) self.lvh_pages.remove(page_id) @@ -2982,7 +2998,7 @@ class HASPmota var obj_id = int(jline.find("id")) # id number or nil var obj_type = jline.find("obj") # obj class or nil obj_type = (obj_type != nil) ? str(obj_type) : nil - var lvh_page_cur = self.get_page_cur() # current page object, cannot be nil + var lvh_page_cur = self.get_page_cur_parsing() # current page object, cannot be nil # Step 1. Check the id for valid range # 'obj_id' must be between 1 and 254 @@ -3063,7 +3079,7 @@ class HASPmota print(f"HSP: cannot specify 'obj':'{obj_type}' for 'id':0") return end - obj_lvh = self.get_page_cur().get_obj(0) # get object id '0' + obj_lvh = self.get_page_cur_parsing().get_obj(0) # get object id '0' end # Step 5. apply attributes diff --git a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h index cb246dc39..2e72d3e11 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h +++ b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h @@ -10932,345 +10932,137 @@ be_local_class(lvh_page, be_str_weak(lvh_page) ); extern const bclass be_class_HASPmota; -// compact class 'HASPmota' ktab size: 122, total: 190 (saved 544 bytes) -static const bvalue be_ktab_class_HASPmota[122] = { - /* K0 */ be_const_class(be_class_HASPmota), - /* K1 */ be_nested_str_weak(introspect), - /* K2 */ be_nested_str_weak(get), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(version), - /* K5 */ be_nested_str_weak(int), - /* K6 */ be_nested_str_weak(json), - /* K7 */ be_nested_str_weak(load), - /* K8 */ be_nested_str_weak(instance), - /* K9 */ be_nested_str_weak(parse_page), - /* K10 */ be_nested_str_weak(parse_obj), - /* K11 */ be_nested_str_weak(lvh_pages), - /* K12 */ be_nested_str_weak(lvh_page_cur_idx), - /* K13 */ be_nested_str_weak(value_error), - /* K14 */ be_nested_str_weak(unable_X20to_X20parse_X20JSON_X20line), - /* K15 */ be_const_int(0), - /* K16 */ be_nested_str_weak(keys), - /* K17 */ be_nested_str_weak(push), - /* K18 */ be_nested_str_weak(stop_iteration), - /* K19 */ be_nested_str_weak(sort), - /* K20 */ be_nested_str_weak(find), - /* K21 */ be_const_int(1), - /* K22 */ be_nested_str_weak(fix_lv_version), - /* K23 */ be_nested_str_weak(re), - /* K24 */ be_nested_str_weak(re_page_target), - /* K25 */ be_nested_str_weak(compile), - /* K26 */ be_nested_str_weak(p_X5Cd_X2B), - /* K27 */ be_nested_str_weak(has), - /* K28 */ be_nested_str_weak(page), - /* K29 */ be_nested_str_weak(contains), - /* K30 */ be_nested_str_weak(lvh_page), - /* K31 */ be_nested_str_weak(id), - /* K32 */ be_nested_str_weak(get_page_cur), - /* K33 */ be_nested_str_weak(prev), - /* K34 */ be_nested_str_weak(next), - /* K35 */ be_nested_str_weak(back), - /* K36 */ be_nested_str_weak(EVENT_CLICKED), - /* K37 */ be_nested_str_weak(page_show), - /* K38 */ be_nested_str_weak(_action), - /* K39 */ be_nested_str_weak(cb), - /* K40 */ be_nested_str_weak(event_cb), - /* K41 */ be_nested_str_weak(gen_cb), - /* K42 */ be_nested_str_weak(_lv_obj), - /* K43 */ be_nested_str_weak(add_event_cb), - /* K44 */ be_nested_str_weak(toptr), - /* K45 */ be_nested_str_weak(string), - /* K46 */ be_nested_str_weak(r), - /* K47 */ be_nested_str_weak(read), - /* K48 */ be_nested_str_weak(close), - /* K49 */ be_nested_str_weak(split), - /* K50 */ be_nested_str_weak(_X0A), - /* K51 */ be_nested_str_weak(tasmota), - /* K52 */ be_nested_str_weak(loglevel), - /* K53 */ be_nested_str_weak(log), - /* K54 */ be_nested_str_weak(HSP_X3A_X20parsing_X20line_X20_X27_X25s_X27), - /* K55 */ be_nested_str_weak(no_X20page_X20_X27id_X27_X20defined), - /* K56 */ be_nested_str_weak(tr), - /* K57 */ be_nested_str_weak(_X20_X09), - /* K58 */ be_nested_str_weak(), - /* K59 */ be_nested_str_weak(HSP_X3A_X20invalid_X20JSON_X20line_X20_X27_X25s_X27), - /* K60 */ be_const_int(2), - /* K61 */ be_nested_str_weak(remove), - /* K62 */ be_nested_str_weak(pages_list_sorted), - /* K63 */ be_nested_str_weak(no_X20page_X20object_X20defined), - /* K64 */ be_nested_str_weak(show), - /* K65 */ be_nested_str_weak(delete), - /* K66 */ be_nested_str_weak(match), - /* K67 */ be_nested_str_weak(path), - /* K68 */ be_nested_str_weak(def_templ_name), - /* K69 */ be_nested_str_weak(exists), - /* K70 */ be_nested_str_weak(file_X20_X27), - /* K71 */ be_nested_str_weak(_X27_X20not_X20found), - /* K72 */ be_nested_str_weak(io_erorr), - /* K73 */ be_nested_str_weak(start), - /* K74 */ be_nested_str_weak(dark), - /* K75 */ be_nested_str_weak(hres), - /* K76 */ be_nested_str_weak(get_hor_res), - /* K77 */ be_nested_str_weak(vres), - /* K78 */ be_nested_str_weak(get_ver_res), - /* K79 */ be_nested_str_weak(scr), - /* K80 */ be_nested_str_weak(scr_act), - /* K81 */ be_nested_str_weak(r16), - /* K82 */ be_nested_str_weak(font_embedded), - /* K83 */ be_nested_str_weak(robotocondensed), - /* K84 */ be_nested_str_weak(montserrat), - /* K85 */ be_nested_str_weak(theme_haspmota_init), - /* K86 */ be_nested_str_weak(color), - /* K87 */ be_const_int(16711935), - /* K88 */ be_const_int(3158064), - /* K89 */ be_nested_str_weak(get_disp), - /* K90 */ be_nested_str_weak(set_theme), - /* K91 */ be_nested_str_weak(set_style_bg_color), - /* K92 */ be_const_int(16777215), - /* K93 */ be_nested_str_weak(theme_apply), - /* K94 */ be_nested_str_weak(layer_top), - /* K95 */ be_nested_str_weak(set_style_bg_opa), - /* K96 */ be_nested_str_weak(_load), - /* K97 */ be_nested_str_weak(global), - /* K98 */ be_nested_str_weak(p_X25s), - /* K99 */ be_nested_str_weak(obj), - /* K100 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20_X25s_X20for_X20_X27obj_X27_X3A_X20_X25s), - /* K101 */ be_nested_str_weak(get_obj), - /* K102 */ be_nested_str_weak(parentid), - /* K103 */ be_nested_str_weak(get_scr), - /* K104 */ be_nested_str_weak(lvh_), - /* K105 */ be_nested_str_weak(class), - /* K106 */ be_nested_str_weak(lvh_obj), - /* K107 */ be_nested_str_weak(module), - /* K108 */ be_nested_str_weak(HSP_X3A_X20Cannot_X20find_X20object_X20of_X20type_X20_X25s), - /* K109 */ be_nested_str_weak(add_obj), - /* K110 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X3A_X27_X25s_X27_X20for_X20_X27id_X27_X3A0), - /* K111 */ be_nested_str_weak(post_config), - /* K112 */ be_nested_str_weak(berry_run), - /* K113 */ be_nested_str_weak(nil), - /* K114 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K115 */ be_nested_str_weak(function), - /* K116 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K117 */ be_nested_str_weak(event), - /* K118 */ be_nested_str_weak(_p), - /* K119 */ be_nested_str_weak(lv_event), - /* K120 */ be_nested_str_weak(get_user_data), - /* K121 */ be_nested_str_weak(fromptr), +// compact class 'HASPmota' ktab size: 124, total: 196 (saved 576 bytes) +static const bvalue be_ktab_class_HASPmota[124] = { + /* K0 */ be_nested_str_weak(has), + /* K1 */ be_nested_str_weak(page), + /* K2 */ be_nested_str_weak(int), + /* K3 */ be_nested_str_weak(lvh_page_cur_idx_parsing), + /* K4 */ be_nested_str_weak(lvh_page_cur_idx), + /* K5 */ be_nested_str_weak(lvh_pages), + /* K6 */ be_nested_str_weak(contains), + /* K7 */ be_nested_str_weak(lvh_page), + /* K8 */ be_nested_str_weak(find), + /* K9 */ be_nested_str_weak(id), + /* K10 */ be_const_int(0), + /* K11 */ be_nested_str_weak(get_page_cur_parsing), + /* K12 */ be_nested_str_weak(prev), + /* K13 */ be_nested_str_weak(next), + /* K14 */ be_nested_str_weak(back), + /* K15 */ be_nested_str_weak(get_page_cur), + /* K16 */ be_nested_str_weak(pages_list_sorted), + /* K17 */ be_const_int(1), + /* K18 */ be_nested_str_weak(delete), + /* K19 */ be_nested_str_weak(re_page_target), + /* K20 */ be_nested_str_weak(match), + /* K21 */ be_nested_str_weak(show), + /* K22 */ be_nested_str_weak(global), + /* K23 */ be_nested_str_weak(introspect), + /* K24 */ be_nested_str_weak(obj), + /* K25 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20_X25s_X20for_X20_X27obj_X27_X3A_X20_X25s), + /* K26 */ be_nested_str_weak(get_obj), + /* K27 */ be_nested_str_weak(parentid), + /* K28 */ be_nested_str_weak(_lv_obj), + /* K29 */ be_nested_str_weak(get_scr), + /* K30 */ be_nested_str_weak(get), + /* K31 */ be_nested_str_weak(lvh_), + /* K32 */ be_nested_str_weak(class), + /* K33 */ be_nested_str_weak(lvh_obj), + /* K34 */ be_nested_str_weak(module), + /* K35 */ be_nested_str_weak(HSP_X3A_X20Cannot_X20find_X20object_X20of_X20type_X20_X25s), + /* K36 */ be_nested_str_weak(add_obj), + /* K37 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X3A_X27_X25s_X27_X20for_X20_X27id_X27_X3A0), + /* K38 */ be_nested_str_weak(keys), + /* K39 */ be_nested_str_weak(stop_iteration), + /* K40 */ be_nested_str_weak(post_config), + /* K41 */ be_nested_str_weak(berry_run), + /* K42 */ be_nested_str_weak(nil), + /* K43 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K44 */ be_nested_str_weak(function), + /* K45 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K46 */ be_nested_str_weak(page_show), + /* K47 */ be_nested_str_weak(remove), + /* K48 */ be_nested_str_weak(p_X25s), + /* K49 */ be_nested_str_weak(push), + /* K50 */ be_nested_str_weak(sort), + /* K51 */ be_nested_str_weak(toptr), + /* K52 */ be_nested_str_weak(event), + /* K53 */ be_nested_str_weak(_p), + /* K54 */ be_nested_str_weak(lv), + /* K55 */ be_nested_str_weak(lv_event), + /* K56 */ be_nested_str_weak(get_user_data), + /* K57 */ be_nested_str_weak(fromptr), + /* K58 */ be_nested_str_weak(instance), + /* K59 */ be_nested_str_weak(event_cb), + /* K60 */ be_const_class(be_class_HASPmota), + /* K61 */ be_nested_str_weak(version), + /* K62 */ be_nested_str_weak(cb), + /* K63 */ be_nested_str_weak(gen_cb), + /* K64 */ be_nested_str_weak(add_event_cb), + /* K65 */ be_nested_str_weak(json), + /* K66 */ be_nested_str_weak(load), + /* K67 */ be_nested_str_weak(parse_page), + /* K68 */ be_nested_str_weak(parse_obj), + /* K69 */ be_nested_str_weak(value_error), + /* K70 */ be_nested_str_weak(unable_X20to_X20parse_X20JSON_X20line), + /* K71 */ be_nested_str_weak(fix_lv_version), + /* K72 */ be_nested_str_weak(re), + /* K73 */ be_nested_str_weak(compile), + /* K74 */ be_nested_str_weak(p_X5Cd_X2B), + /* K75 */ be_nested_str_weak(path), + /* K76 */ be_nested_str_weak(def_templ_name), + /* K77 */ be_nested_str_weak(exists), + /* K78 */ be_nested_str_weak(file_X20_X27), + /* K79 */ be_nested_str_weak(_X27_X20not_X20found), + /* K80 */ be_nested_str_weak(io_erorr), + /* K81 */ be_nested_str_weak(start), + /* K82 */ be_nested_str_weak(dark), + /* K83 */ be_nested_str_weak(hres), + /* K84 */ be_nested_str_weak(get_hor_res), + /* K85 */ be_nested_str_weak(vres), + /* K86 */ be_nested_str_weak(get_ver_res), + /* K87 */ be_nested_str_weak(scr), + /* K88 */ be_nested_str_weak(scr_act), + /* K89 */ be_nested_str_weak(r16), + /* K90 */ be_nested_str_weak(font_embedded), + /* K91 */ be_nested_str_weak(robotocondensed), + /* K92 */ be_nested_str_weak(montserrat), + /* K93 */ be_nested_str_weak(theme_haspmota_init), + /* K94 */ be_nested_str_weak(color), + /* K95 */ be_const_int(16711935), + /* K96 */ be_const_int(3158064), + /* K97 */ be_nested_str_weak(get_disp), + /* K98 */ be_nested_str_weak(set_theme), + /* K99 */ be_nested_str_weak(set_style_bg_color), + /* K100 */ be_const_int(16777215), + /* K101 */ be_nested_str_weak(theme_apply), + /* K102 */ be_nested_str_weak(layer_top), + /* K103 */ be_nested_str_weak(set_style_bg_opa), + /* K104 */ be_nested_str_weak(_load), + /* K105 */ be_const_int(2), + /* K106 */ be_nested_str_weak(EVENT_CLICKED), + /* K107 */ be_nested_str_weak(_action), + /* K108 */ be_nested_str_weak(string), + /* K109 */ be_nested_str_weak(r), + /* K110 */ be_nested_str_weak(read), + /* K111 */ be_nested_str_weak(close), + /* K112 */ be_nested_str_weak(split), + /* K113 */ be_nested_str_weak(_X0A), + /* K114 */ be_nested_str_weak(tasmota), + /* K115 */ be_nested_str_weak(loglevel), + /* K116 */ be_nested_str_weak(log), + /* K117 */ be_nested_str_weak(HSP_X3A_X20parsing_X20line_X20_X27_X25s_X27), + /* K118 */ be_nested_str_weak(no_X20page_X20_X27id_X27_X20defined), + /* K119 */ be_nested_str_weak(tr), + /* K120 */ be_nested_str_weak(_X20_X09), + /* K121 */ be_nested_str_weak(), + /* K122 */ be_nested_str_weak(HSP_X3A_X20invalid_X20JSON_X20line_X20_X27_X25s_X27), + /* K123 */ be_nested_str_weak(no_X20page_X20object_X20defined), }; extern const bclass be_class_HASPmota; -/******************************************************************** -** Solidified function: fix_lv_version -********************************************************************/ -be_local_closure(class_HASPmota_fix_lv_version, /* name */ - be_nested_proto( - 6, /* nstack */ - 0, /* argc */ - 12, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(fix_lv_version), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x58000000, // 0000 LDCONST R0 K0 - 0xA4060200, // 0001 IMPORT R1 K1 - 0x8C080302, // 0002 GETMET R2 R1 K2 - 0xB8120600, // 0003 GETNGBL R4 K3 - 0x58140004, // 0004 LDCONST R5 K4 - 0x7C080600, // 0005 CALL R2 3 - 0x600C0004, // 0006 GETGBL R3 G4 - 0x5C100400, // 0007 MOVE R4 R2 - 0x7C0C0200, // 0008 CALL R3 1 - 0x200C0705, // 0009 NE R3 R3 K5 - 0x780E0002, // 000A JMPF R3 #000E - 0xB80E0600, // 000B GETNGBL R3 K3 - 0x54120007, // 000C LDINT R4 8 - 0x900E0804, // 000D SETMBR R3 K4 R4 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: parse -********************************************************************/ -be_local_closure(class_HASPmota_parse, /* name */ - be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(parse), - &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0xA40A0C00, // 0000 IMPORT R2 K6 - 0x8C0C0507, // 0001 GETMET R3 R2 K7 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x60100004, // 0004 GETGBL R4 G4 - 0x5C140600, // 0005 MOVE R5 R3 - 0x7C100200, // 0006 CALL R4 1 - 0x1C100908, // 0007 EQ R4 R4 K8 - 0x78120009, // 0008 JMPF R4 #0013 - 0x8C100109, // 0009 GETMET R4 R0 K9 - 0x5C180600, // 000A MOVE R6 R3 - 0x7C100400, // 000B CALL R4 2 - 0x8C10010A, // 000C GETMET R4 R0 K10 - 0x5C180600, // 000D MOVE R6 R3 - 0x881C010B, // 000E GETMBR R7 R0 K11 - 0x8820010C, // 000F GETMBR R8 R0 K12 - 0x941C0E08, // 0010 GETIDX R7 R7 R8 - 0x7C100600, // 0011 CALL R4 3 - 0x70020000, // 0012 JMP #0014 - 0xB0061B0E, // 0013 RAISE 1 K13 K14 - 0x80000000, // 0014 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pages_list_sorted -********************************************************************/ -be_local_closure(class_HASPmota_pages_list_sorted, /* name */ - be_nested_proto( - 8, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(pages_list_sorted), - &be_const_str_solidified, - ( &(const binstruction[47]) { /* code */ - 0x60080012, // 0000 GETGBL R2 G18 - 0x7C080000, // 0001 CALL R2 0 - 0x1C0C030F, // 0002 EQ R3 R1 K15 - 0x780E0000, // 0003 JMPF R3 #0005 - 0x8804010C, // 0004 GETMBR R1 R0 K12 - 0x600C0010, // 0005 GETGBL R3 G16 - 0x8810010B, // 0006 GETMBR R4 R0 K11 - 0x8C100910, // 0007 GETMET R4 R4 K16 - 0x7C100200, // 0008 CALL R4 1 - 0x7C0C0200, // 0009 CALL R3 1 - 0xA8020007, // 000A EXBLK 0 #0013 - 0x5C100600, // 000B MOVE R4 R3 - 0x7C100000, // 000C CALL R4 0 - 0x2014090F, // 000D NE R5 R4 K15 - 0x78160002, // 000E JMPF R5 #0012 - 0x8C140511, // 000F GETMET R5 R2 K17 - 0x5C1C0800, // 0010 MOVE R7 R4 - 0x7C140400, // 0011 CALL R5 2 - 0x7001FFF7, // 0012 JMP #000B - 0x580C0012, // 0013 LDCONST R3 K18 - 0xAC0C0200, // 0014 CATCH R3 1 0 - 0xB0080000, // 0015 RAISE 2 R0 R0 - 0x8C0C0113, // 0016 GETMET R3 R0 K19 - 0x5C140400, // 0017 MOVE R5 R2 - 0x7C0C0400, // 0018 CALL R3 2 - 0x5C080600, // 0019 MOVE R2 R3 - 0x4C0C0000, // 001A LDNIL R3 - 0x1C0C0203, // 001B EQ R3 R1 R3 - 0x780E0000, // 001C JMPF R3 #001E - 0x80040400, // 001D RET 1 R2 - 0x600C000C, // 001E GETGBL R3 G12 - 0x5C100400, // 001F MOVE R4 R2 - 0x7C0C0200, // 0020 CALL R3 1 - 0x00080402, // 0021 ADD R2 R2 R2 - 0x8C100514, // 0022 GETMET R4 R2 K20 - 0x5C180200, // 0023 MOVE R6 R1 - 0x7C100400, // 0024 CALL R4 2 - 0x4C140000, // 0025 LDNIL R5 - 0x1C140805, // 0026 EQ R5 R4 R5 - 0x78160001, // 0027 JMPF R5 #002A - 0x4C140000, // 0028 LDNIL R5 - 0x80040A00, // 0029 RET 1 R5 - 0x00140803, // 002A ADD R5 R4 R3 - 0x04140B15, // 002B SUB R5 R5 K21 - 0x40140805, // 002C CONNECT R5 R4 R5 - 0x94080405, // 002D GETIDX R2 R2 R5 - 0x80040400, // 002E RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(class_HASPmota_init, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x8C040116, // 0000 GETMET R1 R0 K22 - 0x7C040200, // 0001 CALL R1 1 - 0xA4062E00, // 0002 IMPORT R1 K23 - 0x8C080319, // 0003 GETMET R2 R1 K25 - 0x5810001A, // 0004 LDCONST R4 K26 - 0x7C080400, // 0005 CALL R2 2 - 0x90023002, // 0006 SETMBR R0 K24 R2 - 0x80000000, // 0007 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_page_cur -********************************************************************/ -be_local_closure(class_HASPmota_get_page_cur, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(get_page_cur), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8804010B, // 0000 GETMBR R1 R0 K11 - 0x8808010C, // 0001 GETMBR R2 R0 K12 - 0x94040202, // 0002 GETIDX R1 R1 R2 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: parse_page ********************************************************************/ @@ -11287,338 +11079,66 @@ be_local_closure(class_HASPmota_parse_page, /* name */ &be_ktab_class_HASPmota, /* shared constants */ be_str_weak(parse_page), &be_const_str_solidified, - ( &(const binstruction[54]) { /* code */ - 0x8C08031B, // 0000 GETMET R2 R1 K27 - 0x5810001C, // 0001 LDCONST R4 K28 + ( &(const binstruction[59]) { /* code */ + 0x8C080300, // 0000 GETMET R2 R1 K0 + 0x58100001, // 0001 LDCONST R4 K1 0x7C080400, // 0002 CALL R2 2 - 0x780A0030, // 0003 JMPF R2 #0035 + 0x780A0035, // 0003 JMPF R2 #003A 0x60080004, // 0004 GETGBL R2 G4 - 0x940C031C, // 0005 GETIDX R3 R1 K28 + 0x940C0301, // 0005 GETIDX R3 R1 K1 0x7C080200, // 0006 CALL R2 1 - 0x1C080505, // 0007 EQ R2 R2 K5 - 0x780A002B, // 0008 JMPF R2 #0035 + 0x1C080502, // 0007 EQ R2 R2 K2 + 0x780A0030, // 0008 JMPF R2 #003A 0x60080009, // 0009 GETGBL R2 G9 - 0x940C031C, // 000A GETIDX R3 R1 K28 + 0x940C0301, // 000A GETIDX R3 R1 K1 0x7C080200, // 000B CALL R2 1 - 0x90021802, // 000C SETMBR R0 K12 R2 - 0x880C010B, // 000D GETMBR R3 R0 K11 - 0x8C0C071D, // 000E GETMET R3 R3 K29 - 0x5C140400, // 000F MOVE R5 R2 - 0x7C0C0400, // 0010 CALL R3 2 - 0x740E0006, // 0011 JMPT R3 #0019 - 0x880C011E, // 0012 GETMBR R3 R0 K30 - 0x8810010B, // 0013 GETMBR R4 R0 K11 - 0x5C140600, // 0014 MOVE R5 R3 - 0x5C180400, // 0015 MOVE R6 R2 - 0x5C1C0000, // 0016 MOVE R7 R0 - 0x7C140400, // 0017 CALL R5 2 - 0x98100405, // 0018 SETIDX R4 R2 R5 - 0x8C0C0314, // 0019 GETMET R3 R1 K20 - 0x5814001F, // 001A LDCONST R5 K31 - 0x7C0C0400, // 001B CALL R3 2 - 0x1C0C070F, // 001C EQ R3 R3 K15 - 0x780E0016, // 001D JMPF R3 #0035 - 0x8C0C0120, // 001E GETMET R3 R0 K32 - 0x7C0C0200, // 001F CALL R3 1 - 0x60100009, // 0020 GETGBL R4 G9 - 0x8C140314, // 0021 GETMET R5 R1 K20 - 0x581C0021, // 0022 LDCONST R7 K33 - 0x4C200000, // 0023 LDNIL R8 - 0x7C140600, // 0024 CALL R5 3 - 0x7C100200, // 0025 CALL R4 1 - 0x900E4204, // 0026 SETMBR R3 K33 R4 - 0x60100009, // 0027 GETGBL R4 G9 - 0x8C140314, // 0028 GETMET R5 R1 K20 - 0x581C0022, // 0029 LDCONST R7 K34 - 0x4C200000, // 002A LDNIL R8 - 0x7C140600, // 002B CALL R5 3 - 0x7C100200, // 002C CALL R4 1 - 0x900E4404, // 002D SETMBR R3 K34 R4 - 0x60100009, // 002E GETGBL R4 G9 - 0x8C140314, // 002F GETMET R5 R1 K20 - 0x581C0023, // 0030 LDCONST R7 K35 - 0x4C200000, // 0031 LDNIL R8 - 0x7C140600, // 0032 CALL R5 3 - 0x7C100200, // 0033 CALL R4 1 - 0x900E4604, // 0034 SETMBR R3 K35 R4 - 0x80000000, // 0035 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: do_action -********************************************************************/ -be_local_closure(class_HASPmota_do_action, /* name */ - be_nested_proto( - 6, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(do_action), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0xB80E0600, // 0000 GETNGBL R3 K3 - 0x880C0724, // 0001 GETMBR R3 R3 K36 - 0x200C0403, // 0002 NE R3 R2 R3 - 0x780E0000, // 0003 JMPF R3 #0005 - 0x80000600, // 0004 RET 0 - 0x8C0C0125, // 0005 GETMET R3 R0 K37 - 0x88140326, // 0006 GETMBR R5 R1 K38 - 0x7C0C0400, // 0007 CALL R3 2 - 0x80000000, // 0008 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: register_event -********************************************************************/ -be_local_closure(class_HASPmota_register_event, /* name */ - be_nested_proto( - 13, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(event_dispatch), - }), - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x68040000, // 0000 GETUPV R1 U0 - 0x8C040300, // 0001 GETMET R1 R1 K0 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C040400, // 0003 CALL R1 2 - 0x80040200, // 0004 RET 1 R1 - }) - ), - }), - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(register_event), - &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0xA40E4E00, // 0000 IMPORT R3 K39 - 0xA4120200, // 0001 IMPORT R4 K1 - 0x88140128, // 0002 GETMBR R5 R0 K40 - 0x4C180000, // 0003 LDNIL R6 - 0x1C140A06, // 0004 EQ R5 R5 R6 - 0x78160003, // 0005 JMPF R5 #000A - 0x8C140729, // 0006 GETMET R5 R3 K41 - 0x841C0000, // 0007 CLOSURE R7 P0 - 0x7C140400, // 0008 CALL R5 2 - 0x90025005, // 0009 SETMBR R0 K40 R5 - 0x8814032A, // 000A GETMBR R5 R1 K42 - 0x8C180B2B, // 000B GETMET R6 R5 K43 - 0x88200128, // 000C GETMBR R8 R0 K40 - 0x5C240400, // 000D MOVE R9 R2 - 0x8C28092C, // 000E GETMET R10 R4 K44 - 0x5C300200, // 000F MOVE R12 R1 - 0x7C280400, // 0010 CALL R10 2 - 0x7C180800, // 0011 CALL R6 4 - 0xA0000000, // 0012 CLOSE R0 - 0x80000000, // 0013 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: _load -********************************************************************/ -be_local_closure(class_HASPmota__load, /* name */ - be_nested_proto( - 14, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(_load), - &be_const_str_solidified, - ( &(const binstruction[99]) { /* code */ - 0xA40A5A00, // 0000 IMPORT R2 K45 - 0xA40E0C00, // 0001 IMPORT R3 K6 - 0x60100011, // 0002 GETGBL R4 G17 - 0x5C140200, // 0003 MOVE R5 R1 - 0x5818002E, // 0004 LDCONST R6 K46 - 0x7C100400, // 0005 CALL R4 2 - 0x8C14092F, // 0006 GETMET R5 R4 K47 - 0x7C140200, // 0007 CALL R5 1 - 0x8C180930, // 0008 GETMET R6 R4 K48 - 0x7C180200, // 0009 CALL R6 1 - 0x8C180531, // 000A GETMET R6 R2 K49 - 0x5C200A00, // 000B MOVE R8 R5 - 0x58240032, // 000C LDCONST R9 K50 - 0x7C180600, // 000D CALL R6 3 + 0x90020602, // 000C SETMBR R0 K3 R2 + 0x880C0104, // 000D GETMBR R3 R0 K4 0x4C100000, // 000E LDNIL R4 - 0x4C140000, // 000F LDNIL R5 - 0x601C000C, // 0010 GETGBL R7 G12 - 0x5C200C00, // 0011 MOVE R8 R6 - 0x7C1C0200, // 0012 CALL R7 1 - 0x241C0F0F, // 0013 GT R7 R7 K15 - 0x781E0039, // 0014 JMPF R7 #004F - 0x8C1C0707, // 0015 GETMET R7 R3 K7 - 0x94240D0F, // 0016 GETIDX R9 R6 K15 - 0x7C1C0400, // 0017 CALL R7 2 - 0x60200004, // 0018 GETGBL R8 G4 - 0x5C240E00, // 0019 MOVE R9 R7 - 0x7C200200, // 001A CALL R8 1 - 0x1C201108, // 001B EQ R8 R8 K8 - 0x7822001B, // 001C JMPF R8 #0039 - 0xB8226600, // 001D GETNGBL R8 K51 - 0x8C201134, // 001E GETMET R8 R8 K52 - 0x542A0003, // 001F LDINT R10 4 - 0x7C200400, // 0020 CALL R8 2 - 0x78220007, // 0021 JMPF R8 #002A - 0xB8226600, // 0022 GETNGBL R8 K51 - 0x8C201135, // 0023 GETMET R8 R8 K53 - 0x60280018, // 0024 GETGBL R10 G24 - 0x582C0036, // 0025 LDCONST R11 K54 - 0x94300D0F, // 0026 GETIDX R12 R6 K15 - 0x7C280400, // 0027 CALL R10 2 - 0x542E0003, // 0028 LDINT R11 4 - 0x7C200600, // 0029 CALL R8 3 - 0x8C200109, // 002A GETMET R8 R0 K9 - 0x5C280E00, // 002B MOVE R10 R7 - 0x7C200400, // 002C CALL R8 2 - 0x8820010B, // 002D GETMBR R8 R0 K11 - 0x4C240000, // 002E LDNIL R9 - 0x1C201009, // 002F EQ R8 R8 R9 - 0x78220000, // 0030 JMPF R8 #0032 - 0xB0061B37, // 0031 RAISE 1 K13 K55 - 0x8C20010A, // 0032 GETMET R8 R0 K10 - 0x5C280E00, // 0033 MOVE R10 R7 - 0x882C010B, // 0034 GETMBR R11 R0 K11 - 0x8830010C, // 0035 GETMBR R12 R0 K12 - 0x942C160C, // 0036 GETIDX R11 R11 R12 - 0x7C200600, // 0037 CALL R8 3 - 0x70020010, // 0038 JMP #004A - 0x6020000C, // 0039 GETGBL R8 G12 - 0x8C240538, // 003A GETMET R9 R2 K56 - 0x942C0D0F, // 003B GETIDX R11 R6 K15 - 0x58300039, // 003C LDCONST R12 K57 - 0x5834003A, // 003D LDCONST R13 K58 - 0x7C240800, // 003E CALL R9 4 - 0x7C200200, // 003F CALL R8 1 - 0x2420110F, // 0040 GT R8 R8 K15 - 0x78220007, // 0041 JMPF R8 #004A - 0xB8226600, // 0042 GETNGBL R8 K51 - 0x8C201135, // 0043 GETMET R8 R8 K53 - 0x60280018, // 0044 GETGBL R10 G24 - 0x582C003B, // 0045 LDCONST R11 K59 - 0x94300D0F, // 0046 GETIDX R12 R6 K15 - 0x7C280400, // 0047 CALL R10 2 - 0x582C003C, // 0048 LDCONST R11 K60 - 0x7C200600, // 0049 CALL R8 3 - 0x4C1C0000, // 004A LDNIL R7 - 0x8C200D3D, // 004B GETMET R8 R6 K61 - 0x5828000F, // 004C LDCONST R10 K15 - 0x7C200400, // 004D CALL R8 2 - 0x7001FFC0, // 004E JMP #0010 - 0x4C180000, // 004F LDNIL R6 - 0x8C1C013E, // 0050 GETMET R7 R0 K62 - 0x4C240000, // 0051 LDNIL R9 - 0x7C1C0400, // 0052 CALL R7 2 - 0x6020000C, // 0053 GETGBL R8 G12 - 0x5C240E00, // 0054 MOVE R9 R7 - 0x7C200200, // 0055 CALL R8 1 - 0x1C20110F, // 0056 EQ R8 R8 K15 - 0x78220000, // 0057 JMPF R8 #0059 - 0xB0061B3F, // 0058 RAISE 1 K13 K63 - 0x94200F0F, // 0059 GETIDX R8 R7 K15 - 0x90021808, // 005A SETMBR R0 K12 R8 - 0x8820010B, // 005B GETMBR R8 R0 K11 - 0x8824010C, // 005C GETMBR R9 R0 K12 - 0x94201009, // 005D GETIDX R8 R8 R9 - 0x8C201140, // 005E GETMET R8 R8 K64 - 0x5828000F, // 005F LDCONST R10 K15 - 0x582C000F, // 0060 LDCONST R11 K15 - 0x7C200600, // 0061 CALL R8 3 - 0x80000000, // 0062 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: page_dir_to -********************************************************************/ -be_local_closure(class_HASPmota_page_dir_to, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(page_dir_to), - &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ - 0x8C08013E, // 0000 GETMET R2 R0 K62 - 0x5810000F, // 0001 LDCONST R4 K15 - 0x7C080400, // 0002 CALL R2 2 - 0x4C0C0000, // 0003 LDNIL R3 - 0x1C0C0403, // 0004 EQ R3 R2 R3 - 0x780E0000, // 0005 JMPF R3 #0007 - 0x80061E00, // 0006 RET 1 K15 - 0x600C000C, // 0007 GETGBL R3 G12 - 0x5C100400, // 0008 MOVE R4 R2 - 0x7C0C0200, // 0009 CALL R3 1 - 0x18100715, // 000A LE R4 R3 K21 - 0x78120000, // 000B JMPF R4 #000D - 0x80061E00, // 000C RET 1 K15 - 0x1C10073C, // 000D EQ R4 R3 K60 - 0x78120000, // 000E JMPF R4 #0010 - 0x80062A00, // 000F RET 1 K21 - 0x8C100514, // 0010 GETMET R4 R2 K20 - 0x5C180200, // 0011 MOVE R6 R1 - 0x7C100400, // 0012 CALL R4 2 - 0x4C140000, // 0013 LDNIL R5 - 0x1C140805, // 0014 EQ R5 R4 R5 - 0x78160000, // 0015 JMPF R5 #0017 - 0x80061E00, // 0016 RET 1 K15 - 0x00140715, // 0017 ADD R5 R3 K21 - 0x0C140B3C, // 0018 DIV R5 R5 K60 - 0x18140805, // 0019 LE R5 R4 R5 - 0x78160001, // 001A JMPF R5 #001D - 0x80062A00, // 001B RET 1 K21 - 0x70020001, // 001C JMP #001F - 0x5415FFFE, // 001D LDINT R5 -1 - 0x80040A00, // 001E RET 1 R5 - 0x80000000, // 001F RET 0 + 0x1C0C0604, // 000F EQ R3 R3 R4 + 0x780E0000, // 0010 JMPF R3 #0012 + 0x90020802, // 0011 SETMBR R0 K4 R2 + 0x880C0105, // 0012 GETMBR R3 R0 K5 + 0x8C0C0706, // 0013 GETMET R3 R3 K6 + 0x5C140400, // 0014 MOVE R5 R2 + 0x7C0C0400, // 0015 CALL R3 2 + 0x740E0006, // 0016 JMPT R3 #001E + 0x880C0107, // 0017 GETMBR R3 R0 K7 + 0x88100105, // 0018 GETMBR R4 R0 K5 + 0x5C140600, // 0019 MOVE R5 R3 + 0x5C180400, // 001A MOVE R6 R2 + 0x5C1C0000, // 001B MOVE R7 R0 + 0x7C140400, // 001C CALL R5 2 + 0x98100405, // 001D SETIDX R4 R2 R5 + 0x8C0C0308, // 001E GETMET R3 R1 K8 + 0x58140009, // 001F LDCONST R5 K9 + 0x7C0C0400, // 0020 CALL R3 2 + 0x1C0C070A, // 0021 EQ R3 R3 K10 + 0x780E0016, // 0022 JMPF R3 #003A + 0x8C0C010B, // 0023 GETMET R3 R0 K11 + 0x7C0C0200, // 0024 CALL R3 1 + 0x60100009, // 0025 GETGBL R4 G9 + 0x8C140308, // 0026 GETMET R5 R1 K8 + 0x581C000C, // 0027 LDCONST R7 K12 + 0x4C200000, // 0028 LDNIL R8 + 0x7C140600, // 0029 CALL R5 3 + 0x7C100200, // 002A CALL R4 1 + 0x900E1804, // 002B SETMBR R3 K12 R4 + 0x60100009, // 002C GETGBL R4 G9 + 0x8C140308, // 002D GETMET R5 R1 K8 + 0x581C000D, // 002E LDCONST R7 K13 + 0x4C200000, // 002F LDNIL R8 + 0x7C140600, // 0030 CALL R5 3 + 0x7C100200, // 0031 CALL R4 1 + 0x900E1A04, // 0032 SETMBR R3 K13 R4 + 0x60100009, // 0033 GETGBL R4 G9 + 0x8C140308, // 0034 GETMET R5 R1 K8 + 0x581C000E, // 0035 LDCONST R7 K14 + 0x4C200000, // 0036 LDNIL R8 + 0x7C140600, // 0037 CALL R5 3 + 0x7C100200, // 0038 CALL R4 1 + 0x900E1C04, // 0039 SETMBR R3 K14 R4 + 0x80000000, // 003A RET 0 }) ) ); @@ -11675,23 +11195,23 @@ be_local_closure(class_HASPmota_page_show, /* name */ ( &(const binstruction[108]) { /* code */ 0x84100000, // 0000 CLOSURE R4 P0 0x4C140000, // 0001 LDNIL R5 - 0x8C180120, // 0002 GETMET R6 R0 K32 + 0x8C18010F, // 0002 GETMET R6 R0 K15 0x7C180200, // 0003 CALL R6 1 - 0x8C1C013E, // 0004 GETMET R7 R0 K62 - 0x8824010C, // 0005 GETMBR R9 R0 K12 + 0x8C1C0110, // 0004 GETMET R7 R0 K16 + 0x88240104, // 0005 GETMBR R9 R0 K4 0x7C1C0400, // 0006 CALL R7 2 0x6020000C, // 0007 GETGBL R8 G12 0x5C240E00, // 0008 MOVE R9 R7 0x7C200200, // 0009 CALL R8 1 - 0x18201115, // 000A LE R8 R8 K21 + 0x18201111, // 000A LE R8 R8 K17 0x78220001, // 000B JMPF R8 #000E 0x4C200000, // 000C LDNIL R8 0x80041000, // 000D RET 1 R8 - 0x1C200321, // 000E EQ R8 R1 K33 + 0x1C20030C, // 000E EQ R8 R1 K12 0x78220009, // 000F JMPF R8 #001A 0x5C200800, // 0010 MOVE R8 R4 0x60240009, // 0011 GETGBL R9 G9 - 0x88280D21, // 0012 GETMBR R10 R6 K33 + 0x88280D0C, // 0012 GETMBR R10 R6 K12 0x7C240200, // 0013 CALL R9 1 0x5429FFFE, // 0014 LDINT R10 -1 0x94280E0A, // 0015 GETIDX R10 R7 R10 @@ -11699,66 +11219,66 @@ be_local_closure(class_HASPmota_page_show, /* name */ 0x7C200600, // 0017 CALL R8 3 0x5C141000, // 0018 MOVE R5 R8 0x70020041, // 0019 JMP #005C - 0x1C200322, // 001A EQ R8 R1 K34 + 0x1C20030D, // 001A EQ R8 R1 K13 0x78220008, // 001B JMPF R8 #0025 0x5C200800, // 001C MOVE R8 R4 0x60240009, // 001D GETGBL R9 G9 - 0x88280D22, // 001E GETMBR R10 R6 K34 + 0x88280D0D, // 001E GETMBR R10 R6 K13 0x7C240200, // 001F CALL R9 1 - 0x94280F15, // 0020 GETIDX R10 R7 K21 + 0x94280F11, // 0020 GETIDX R10 R7 K17 0x5C2C0E00, // 0021 MOVE R11 R7 0x7C200600, // 0022 CALL R8 3 0x5C141000, // 0023 MOVE R5 R8 0x70020036, // 0024 JMP #005C - 0x1C200323, // 0025 EQ R8 R1 K35 + 0x1C20030E, // 0025 EQ R8 R1 K14 0x7822000B, // 0026 JMPF R8 #0033 0x5C200800, // 0027 MOVE R8 R4 0x60240009, // 0028 GETGBL R9 G9 - 0x88280D23, // 0029 GETMBR R10 R6 K35 + 0x88280D0E, // 0029 GETMBR R10 R6 K14 0x7C240200, // 002A CALL R9 1 - 0x8C28013E, // 002B GETMET R10 R0 K62 + 0x8C280110, // 002B GETMET R10 R0 K16 0x4C300000, // 002C LDNIL R12 0x7C280400, // 002D CALL R10 2 - 0x9428150F, // 002E GETIDX R10 R10 K15 + 0x9428150A, // 002E GETIDX R10 R10 K10 0x5C2C0E00, // 002F MOVE R11 R7 0x7C200600, // 0030 CALL R8 3 0x5C141000, // 0031 MOVE R5 R8 0x70020028, // 0032 JMP #005C - 0x1C200341, // 0033 EQ R8 R1 K65 + 0x1C200312, // 0033 EQ R8 R1 K18 0x78220017, // 0034 JMPF R8 #004D 0x5C200800, // 0035 MOVE R8 R4 0x60240009, // 0036 GETGBL R9 G9 - 0x88280D23, // 0037 GETMBR R10 R6 K35 + 0x88280D0E, // 0037 GETMBR R10 R6 K14 0x7C240200, // 0038 CALL R9 1 - 0x8C28013E, // 0039 GETMET R10 R0 K62 + 0x8C280110, // 0039 GETMET R10 R0 K16 0x4C300000, // 003A LDNIL R12 0x7C280400, // 003B CALL R10 2 - 0x9428150F, // 003C GETIDX R10 R10 K15 + 0x9428150A, // 003C GETIDX R10 R10 K10 0x5C2C0E00, // 003D MOVE R11 R7 0x7C200600, // 003E CALL R8 3 0x5C141000, // 003F MOVE R5 R8 - 0x8C200D1F, // 0040 GETMET R8 R6 K31 + 0x8C200D09, // 0040 GETMET R8 R6 K9 0x7C200200, // 0041 CALL R8 1 0x1C200A08, // 0042 EQ R8 R5 R8 0x78220007, // 0043 JMPF R8 #004C 0x5C200800, // 0044 MOVE R8 R4 0x60240009, // 0045 GETGBL R9 G9 - 0x88280D22, // 0046 GETMBR R10 R6 K34 + 0x88280D0D, // 0046 GETMBR R10 R6 K13 0x7C240200, // 0047 CALL R9 1 - 0x94280F15, // 0048 GETIDX R10 R7 K21 + 0x94280F11, // 0048 GETIDX R10 R7 K17 0x5C2C0E00, // 0049 MOVE R11 R7 0x7C200600, // 004A CALL R8 3 0x5C141000, // 004B MOVE R5 R8 0x7002000E, // 004C JMP #005C - 0x88200118, // 004D GETMBR R8 R0 K24 - 0x8C201142, // 004E GETMET R8 R8 K66 + 0x88200113, // 004D GETMBR R8 R0 K19 + 0x8C201114, // 004E GETMET R8 R8 K20 0x5C280200, // 004F MOVE R10 R1 0x7C200400, // 0050 CALL R8 2 0x78220009, // 0051 JMPF R8 #005C 0x5C200800, // 0052 MOVE R8 R4 0x60240009, // 0053 GETGBL R9 G9 0x5429FFFE, // 0054 LDINT R10 -1 - 0x402A2A0A, // 0055 CONNECT R10 K21 R10 + 0x402A220A, // 0055 CONNECT R10 K17 R10 0x9428020A, // 0056 GETIDX R10 R1 R10 0x7C240200, // 0057 CALL R9 1 0x4C280000, // 0058 LDNIL R10 @@ -11768,14 +11288,14 @@ be_local_closure(class_HASPmota_page_show, /* name */ 0x4C200000, // 005C LDNIL R8 0x20200A08, // 005D NE R8 R5 R8 0x7822000B, // 005E JMPF R8 #006B - 0x24200B0F, // 005F GT R8 R5 K15 + 0x24200B0A, // 005F GT R8 R5 K10 0x78220009, // 0060 JMPF R8 #006B - 0x8820010B, // 0061 GETMBR R8 R0 K11 + 0x88200105, // 0061 GETMBR R8 R0 K5 0x94201005, // 0062 GETIDX R8 R8 R5 0x4C240000, // 0063 LDNIL R9 0x20241009, // 0064 NE R9 R8 R9 0x78260003, // 0065 JMPF R9 #006A - 0x8C241140, // 0066 GETMET R9 R8 K64 + 0x8C241115, // 0066 GETMET R9 R8 K21 0x5C2C0400, // 0067 MOVE R11 R2 0x5C300600, // 0068 MOVE R12 R3 0x7C240600, // 0069 CALL R9 3 @@ -11787,242 +11307,6 @@ be_local_closure(class_HASPmota_page_show, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: start -********************************************************************/ -be_local_closure(class_HASPmota_start, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(start), - &be_const_str_solidified, - ( &(const binstruction[105]) { /* code */ - 0xA40E8600, // 0000 IMPORT R3 K67 - 0x4C100000, // 0001 LDNIL R4 - 0x1C100404, // 0002 EQ R4 R2 R4 - 0x78120000, // 0003 JMPF R4 #0005 - 0x88080144, // 0004 GETMBR R2 R0 K68 - 0x8C100745, // 0005 GETMET R4 R3 K69 - 0x5C180400, // 0006 MOVE R6 R2 - 0x7C100400, // 0007 CALL R4 2 - 0x74120002, // 0008 JMPT R4 #000C - 0x00128C02, // 0009 ADD R4 K70 R2 - 0x00100947, // 000A ADD R4 R4 K71 - 0xB0069004, // 000B RAISE 1 K72 R4 - 0xB8120600, // 000C GETNGBL R4 K3 - 0x8C100949, // 000D GETMET R4 R4 K73 - 0x7C100200, // 000E CALL R4 1 - 0x60100017, // 000F GETGBL R4 G23 - 0x5C140200, // 0010 MOVE R5 R1 - 0x7C100200, // 0011 CALL R4 1 - 0x90029404, // 0012 SETMBR R0 K74 R4 - 0xB8120600, // 0013 GETNGBL R4 K3 - 0x8C10094C, // 0014 GETMET R4 R4 K76 - 0x7C100200, // 0015 CALL R4 1 - 0x90029604, // 0016 SETMBR R0 K75 R4 - 0xB8120600, // 0017 GETNGBL R4 K3 - 0x8C10094E, // 0018 GETMET R4 R4 K78 - 0x7C100200, // 0019 CALL R4 1 - 0x90029A04, // 001A SETMBR R0 K77 R4 - 0xB8120600, // 001B GETNGBL R4 K3 - 0x8C100950, // 001C GETMET R4 R4 K80 - 0x7C100200, // 001D CALL R4 1 - 0x90029E04, // 001E SETMBR R0 K79 R4 - 0xA8020007, // 001F EXBLK 0 #0028 - 0xB8120600, // 0020 GETNGBL R4 K3 - 0x8C100952, // 0021 GETMET R4 R4 K82 - 0x58180053, // 0022 LDCONST R6 K83 - 0x541E000F, // 0023 LDINT R7 16 - 0x7C100600, // 0024 CALL R4 3 - 0x9002A204, // 0025 SETMBR R0 K81 R4 - 0xA8040001, // 0026 EXBLK 1 1 - 0x70020009, // 0027 JMP #0032 - 0xAC100000, // 0028 CATCH R4 0 0 - 0x70020006, // 0029 JMP #0031 - 0xB8120600, // 002A GETNGBL R4 K3 - 0x8C100952, // 002B GETMET R4 R4 K82 - 0x58180054, // 002C LDCONST R6 K84 - 0x541E000D, // 002D LDINT R7 14 - 0x7C100600, // 002E CALL R4 3 - 0x9002A204, // 002F SETMBR R0 K81 R4 - 0x70020000, // 0030 JMP #0032 - 0xB0080000, // 0031 RAISE 2 R0 R0 - 0xB8120600, // 0032 GETNGBL R4 K3 - 0x8C100955, // 0033 GETMET R4 R4 K85 - 0x5818000F, // 0034 LDCONST R6 K15 - 0xB81E0600, // 0035 GETNGBL R7 K3 - 0x8C1C0F56, // 0036 GETMET R7 R7 K86 - 0x58240057, // 0037 LDCONST R9 K87 - 0x7C1C0400, // 0038 CALL R7 2 - 0xB8220600, // 0039 GETNGBL R8 K3 - 0x8C201156, // 003A GETMET R8 R8 K86 - 0x58280058, // 003B LDCONST R10 K88 - 0x7C200400, // 003C CALL R8 2 - 0x8824014A, // 003D GETMBR R9 R0 K74 - 0x88280151, // 003E GETMBR R10 R0 K81 - 0x7C100C00, // 003F CALL R4 6 - 0x8814014F, // 0040 GETMBR R5 R0 K79 - 0x8C140B59, // 0041 GETMET R5 R5 K89 - 0x7C140200, // 0042 CALL R5 1 - 0x8C140B5A, // 0043 GETMET R5 R5 K90 - 0x5C1C0800, // 0044 MOVE R7 R4 - 0x7C140400, // 0045 CALL R5 2 - 0x8814014F, // 0046 GETMBR R5 R0 K79 - 0x8C140B5B, // 0047 GETMET R5 R5 K91 - 0x881C014A, // 0048 GETMBR R7 R0 K74 - 0x781E0004, // 0049 JMPF R7 #004F - 0xB81E0600, // 004A GETNGBL R7 K3 - 0x8C1C0F56, // 004B GETMET R7 R7 K86 - 0x5824000F, // 004C LDCONST R9 K15 - 0x7C1C0400, // 004D CALL R7 2 - 0x70020003, // 004E JMP #0053 - 0xB81E0600, // 004F GETNGBL R7 K3 - 0x8C1C0F56, // 0050 GETMET R7 R7 K86 - 0x5824005C, // 0051 LDCONST R9 K92 - 0x7C1C0400, // 0052 CALL R7 2 - 0x5820000F, // 0053 LDCONST R8 K15 - 0x7C140600, // 0054 CALL R5 3 - 0xB8160600, // 0055 GETNGBL R5 K3 - 0x8C140B5D, // 0056 GETMET R5 R5 K93 - 0xB81E0600, // 0057 GETNGBL R7 K3 - 0x8C1C0F5E, // 0058 GETMET R7 R7 K94 - 0x7C1C0200, // 0059 CALL R7 1 - 0x7C140400, // 005A CALL R5 2 - 0xB8160600, // 005B GETNGBL R5 K3 - 0x8C140B5E, // 005C GETMET R5 R5 K94 - 0x7C140200, // 005D CALL R5 1 - 0x8C140B5F, // 005E GETMET R5 R5 K95 - 0x581C000F, // 005F LDCONST R7 K15 - 0x5820000F, // 0060 LDCONST R8 K15 - 0x7C140600, // 0061 CALL R5 3 - 0x60140013, // 0062 GETGBL R5 G19 - 0x7C140000, // 0063 CALL R5 0 - 0x90021605, // 0064 SETMBR R0 K11 R5 - 0x8C140160, // 0065 GETMET R5 R0 K96 - 0x5C1C0400, // 0066 MOVE R7 R2 - 0x7C140400, // 0067 CALL R5 2 - 0x80000000, // 0068 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: _remove_page -********************************************************************/ -be_local_closure(class_HASPmota__remove_page, /* name */ - be_nested_proto( - 8, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(_remove_page), - &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ - 0x8C080120, // 0000 GETMET R2 R0 K32 - 0x7C080200, // 0001 CALL R2 1 - 0x8C08051F, // 0002 GETMET R2 R2 K31 - 0x7C080200, // 0003 CALL R2 1 - 0x1C0C0202, // 0004 EQ R3 R1 R2 - 0x780E0008, // 0005 JMPF R3 #000F - 0x8C0C0125, // 0006 GETMET R3 R0 K37 - 0x58140041, // 0007 LDCONST R5 K65 - 0x5818000F, // 0008 LDCONST R6 K15 - 0x581C000F, // 0009 LDCONST R7 K15 - 0x7C0C0800, // 000A CALL R3 4 - 0x4C100000, // 000B LDNIL R4 - 0x1C100604, // 000C EQ R4 R3 R4 - 0x78120000, // 000D JMPF R4 #000F - 0x80000800, // 000E RET 0 - 0x880C010B, // 000F GETMBR R3 R0 K11 - 0x8C0C071D, // 0010 GETMET R3 R3 K29 - 0x5C140200, // 0011 MOVE R5 R1 - 0x7C0C0400, // 0012 CALL R3 2 - 0x780E0003, // 0013 JMPF R3 #0018 - 0x880C010B, // 0014 GETMBR R3 R0 K11 - 0x8C0C073D, // 0015 GETMET R3 R3 K61 - 0x5C140200, // 0016 MOVE R5 R1 - 0x7C0C0400, // 0017 CALL R3 2 - 0x600C0018, // 0018 GETGBL R3 G24 - 0x58100062, // 0019 LDCONST R4 K98 - 0x5C140200, // 001A MOVE R5 R1 - 0x7C0C0400, // 001B CALL R3 2 - 0xB812C200, // 001C GETNGBL R4 K97 - 0x4C140000, // 001D LDNIL R5 - 0x90100605, // 001E SETMBR R4 R3 R5 - 0x80000000, // 001F RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: sort -********************************************************************/ -be_local_closure(class_HASPmota_sort, /* name */ - be_nested_proto( - 7, /* nstack */ - 1, /* argc */ - 12, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(sort), - &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x60080010, // 0001 GETGBL R2 G16 - 0x600C000C, // 0002 GETGBL R3 G12 - 0x5C100000, // 0003 MOVE R4 R0 - 0x7C0C0200, // 0004 CALL R3 1 - 0x040C0715, // 0005 SUB R3 R3 K21 - 0x400E2A03, // 0006 CONNECT R3 K21 R3 - 0x7C080200, // 0007 CALL R2 1 - 0xA8020010, // 0008 EXBLK 0 #001A - 0x5C0C0400, // 0009 MOVE R3 R2 - 0x7C0C0000, // 000A CALL R3 0 - 0x94100003, // 000B GETIDX R4 R0 R3 - 0x5C140600, // 000C MOVE R5 R3 - 0x24180B0F, // 000D GT R6 R5 K15 - 0x781A0008, // 000E JMPF R6 #0018 - 0x04180B15, // 000F SUB R6 R5 K21 - 0x94180006, // 0010 GETIDX R6 R0 R6 - 0x24180C04, // 0011 GT R6 R6 R4 - 0x781A0004, // 0012 JMPF R6 #0018 - 0x04180B15, // 0013 SUB R6 R5 K21 - 0x94180006, // 0014 GETIDX R6 R0 R6 - 0x98000A06, // 0015 SETIDX R0 R5 R6 - 0x04140B15, // 0016 SUB R5 R5 K21 - 0x7001FFF4, // 0017 JMP #000D - 0x98000A04, // 0018 SETIDX R0 R5 R4 - 0x7001FFEE, // 0019 JMP #0009 - 0x58080012, // 001A LDCONST R2 K18 - 0xAC080200, // 001B CATCH R2 1 0 - 0xB0080000, // 001C RAISE 2 R0 R0 - 0x80040000, // 001D RET 1 R0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: parse_obj ********************************************************************/ @@ -12040,15 +11324,15 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ be_str_weak(parse_obj), &be_const_str_solidified, ( &(const binstruction[239]) { /* code */ - 0xA40EC200, // 0000 IMPORT R3 K97 - 0xA4120200, // 0001 IMPORT R4 K1 + 0xA40E2C00, // 0000 IMPORT R3 K22 + 0xA4122E00, // 0001 IMPORT R4 K23 0x60140009, // 0002 GETGBL R5 G9 - 0x8C180314, // 0003 GETMET R6 R1 K20 - 0x5820001F, // 0004 LDCONST R8 K31 + 0x8C180308, // 0003 GETMET R6 R1 K8 + 0x58200009, // 0004 LDCONST R8 K9 0x7C180400, // 0005 CALL R6 2 0x7C140200, // 0006 CALL R5 1 - 0x8C180314, // 0007 GETMET R6 R1 K20 - 0x58200063, // 0008 LDCONST R8 K99 + 0x8C180308, // 0007 GETMET R6 R1 K8 + 0x58200018, // 0008 LDCONST R8 K24 0x7C180400, // 0009 CALL R6 2 0x4C1C0000, // 000A LDNIL R7 0x201C0C07, // 000B NE R7 R6 R7 @@ -12059,30 +11343,30 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x70020000, // 0010 JMP #0012 0x4C1C0000, // 0011 LDNIL R7 0x5C180E00, // 0012 MOVE R6 R7 - 0x8C1C0120, // 0013 GETMET R7 R0 K32 + 0x8C1C010B, // 0013 GETMET R7 R0 K11 0x7C1C0200, // 0014 CALL R7 1 0x4C200000, // 0015 LDNIL R8 0x20200A08, // 0016 NE R8 R5 R8 0x78220011, // 0017 JMPF R8 #002A - 0x14200B0F, // 0018 LT R8 R5 K15 + 0x14200B0A, // 0018 LT R8 R5 K10 0x74220002, // 0019 JMPT R8 #001D 0x542200FD, // 001A LDINT R8 254 0x24200A08, // 001B GT R8 R5 R8 0x7822000C, // 001C JMPF R8 #002A - 0x20200B0F, // 001D NE R8 R5 K15 + 0x20200B0A, // 001D NE R8 R5 K10 0x74220002, // 001E JMPT R8 #0022 0x4C200000, // 001F LDNIL R8 0x1C200C08, // 0020 EQ R8 R6 R8 0x78220007, // 0021 JMPF R8 #002A 0x60200001, // 0022 GETGBL R8 G1 0x60240018, // 0023 GETGBL R9 G24 - 0x58280064, // 0024 LDCONST R10 K100 + 0x58280019, // 0024 LDCONST R10 K25 0x5C2C0A00, // 0025 MOVE R11 R5 0x5C300C00, // 0026 MOVE R12 R6 0x7C240600, // 0027 CALL R9 3 0x7C200200, // 0028 CALL R8 1 0x80001000, // 0029 RET 0 - 0x8C200F65, // 002A GETMET R8 R7 K101 + 0x8C200F1A, // 002A GETMET R8 R7 K26 0x5C280A00, // 002B MOVE R10 R5 0x7C200400, // 002C CALL R8 2 0x4C240000, // 002D LDNIL R9 @@ -12095,8 +11379,8 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x1C241009, // 0034 EQ R9 R8 R9 0x78260059, // 0035 JMPF R9 #0090 0x60240009, // 0036 GETGBL R9 G9 - 0x8C280314, // 0037 GETMET R10 R1 K20 - 0x58300066, // 0038 LDCONST R12 K102 + 0x8C280308, // 0037 GETMET R10 R1 K8 + 0x5830001B, // 0038 LDCONST R12 K27 0x7C280400, // 0039 CALL R10 2 0x7C240200, // 003A CALL R9 1 0x4C280000, // 003B LDNIL R10 @@ -12104,29 +11388,29 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x4C300000, // 003D LDNIL R12 0x2030120C, // 003E NE R12 R9 R12 0x78320007, // 003F JMPF R12 #0048 - 0x8C300F65, // 0040 GETMET R12 R7 K101 + 0x8C300F1A, // 0040 GETMET R12 R7 K26 0x5C381200, // 0041 MOVE R14 R9 0x7C300400, // 0042 CALL R12 2 0x5C281800, // 0043 MOVE R10 R12 0x4C300000, // 0044 LDNIL R12 0x2030140C, // 0045 NE R12 R10 R12 0x78320000, // 0046 JMPF R12 #0048 - 0x882C152A, // 0047 GETMBR R11 R10 K42 + 0x882C151C, // 0047 GETMBR R11 R10 K28 0x4C300000, // 0048 LDNIL R12 0x1C30160C, // 0049 EQ R12 R11 R12 0x78320002, // 004A JMPF R12 #004E - 0x8C300F67, // 004B GETMET R12 R7 K103 + 0x8C300F1D, // 004B GETMET R12 R7 K29 0x7C300200, // 004C CALL R12 1 0x5C2C1800, // 004D MOVE R11 R12 - 0x8C300902, // 004E GETMET R12 R4 K2 + 0x8C30091E, // 004E GETMET R12 R4 K30 0x5C380000, // 004F MOVE R14 R0 - 0x003ED006, // 0050 ADD R15 K104 R6 + 0x003E3E06, // 0050 ADD R15 K31 R6 0x7C300600, // 0051 CALL R12 3 0x4C340000, // 0052 LDNIL R13 0x4C380000, // 0053 LDNIL R14 0x1C38180E, // 0054 EQ R14 R12 R14 0x783A0010, // 0055 JMPF R14 #0067 - 0x8C380902, // 0056 GETMET R14 R4 K2 + 0x8C38091E, // 0056 GETMET R14 R4 K30 0x5C400600, // 0057 MOVE R16 R3 0x5C440C00, // 0058 MOVE R17 R6 0x7C380600, // 0059 CALL R14 3 @@ -12136,17 +11420,17 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x603C0004, // 005D GETGBL R15 G4 0x5C401C00, // 005E MOVE R16 R14 0x7C3C0200, // 005F CALL R15 1 - 0x1C3C1F69, // 0060 EQ R15 R15 K105 + 0x1C3C1F20, // 0060 EQ R15 R15 K32 0x783E0004, // 0061 JMPF R15 #0067 0x5C3C1C00, // 0062 MOVE R15 R14 0x5C401600, // 0063 MOVE R16 R11 0x7C3C0200, // 0064 CALL R15 1 0x5C341E00, // 0065 MOVE R13 R15 - 0x8830016A, // 0066 GETMBR R12 R0 K106 + 0x88300121, // 0066 GETMBR R12 R0 K33 0x4C380000, // 0067 LDNIL R14 0x1C38180E, // 0068 EQ R14 R12 R14 0x783A000F, // 0069 JMPF R14 #007A - 0x8C38096B, // 006A GETMET R14 R4 K107 + 0x8C380922, // 006A GETMET R14 R4 K34 0x5C400C00, // 006B MOVE R16 R6 0x7C380400, // 006C CALL R14 2 0x4C3C0000, // 006D LDNIL R15 @@ -12155,19 +11439,19 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x603C0004, // 0070 GETGBL R15 G4 0x5C401C00, // 0071 MOVE R16 R14 0x7C3C0200, // 0072 CALL R15 1 - 0x1C3C1F69, // 0073 EQ R15 R15 K105 + 0x1C3C1F20, // 0073 EQ R15 R15 K32 0x783E0004, // 0074 JMPF R15 #007A 0x5C3C1C00, // 0075 MOVE R15 R14 0x5C401600, // 0076 MOVE R16 R11 0x7C3C0200, // 0077 CALL R15 1 0x5C341E00, // 0078 MOVE R13 R15 - 0x8830016A, // 0079 GETMBR R12 R0 K106 + 0x88300121, // 0079 GETMBR R12 R0 K33 0x4C380000, // 007A LDNIL R14 0x1C38180E, // 007B EQ R14 R12 R14 0x783A0006, // 007C JMPF R14 #0084 0x60380001, // 007D GETGBL R14 G1 0x603C0018, // 007E GETGBL R15 G24 - 0x5840006C, // 007F LDCONST R16 K108 + 0x58400023, // 007F LDCONST R16 K35 0x5C440C00, // 0080 MOVE R17 R6 0x7C3C0400, // 0081 CALL R15 2 0x7C380200, // 0082 CALL R14 1 @@ -12180,33 +11464,33 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x5C4C1400, // 0089 MOVE R19 R10 0x7C380A00, // 008A CALL R14 5 0x5C201C00, // 008B MOVE R8 R14 - 0x8C380F6D, // 008C GETMET R14 R7 K109 + 0x8C380F24, // 008C GETMET R14 R7 K36 0x5C400A00, // 008D MOVE R16 R5 0x5C441000, // 008E MOVE R17 R8 0x7C380600, // 008F CALL R14 3 - 0x1C240B0F, // 0090 EQ R9 R5 K15 + 0x1C240B0A, // 0090 EQ R9 R5 K10 0x7826000F, // 0091 JMPF R9 #00A2 0x4C240000, // 0092 LDNIL R9 0x20240C09, // 0093 NE R9 R6 R9 0x78260006, // 0094 JMPF R9 #009C 0x60240001, // 0095 GETGBL R9 G1 0x60280018, // 0096 GETGBL R10 G24 - 0x582C006E, // 0097 LDCONST R11 K110 + 0x582C0025, // 0097 LDCONST R11 K37 0x5C300C00, // 0098 MOVE R12 R6 0x7C280400, // 0099 CALL R10 2 0x7C240200, // 009A CALL R9 1 0x80001200, // 009B RET 0 - 0x8C240120, // 009C GETMET R9 R0 K32 + 0x8C24010B, // 009C GETMET R9 R0 K11 0x7C240200, // 009D CALL R9 1 - 0x8C241365, // 009E GETMET R9 R9 K101 - 0x582C000F, // 009F LDCONST R11 K15 + 0x8C24131A, // 009E GETMET R9 R9 K26 + 0x582C000A, // 009F LDCONST R11 K10 0x7C240400, // 00A0 CALL R9 2 0x5C201200, // 00A1 MOVE R8 R9 0x4C240000, // 00A2 LDNIL R9 0x20241009, // 00A3 NE R9 R8 R9 0x7826000C, // 00A4 JMPF R9 #00B2 0x60240010, // 00A5 GETGBL R9 G16 - 0x8C280310, // 00A6 GETMET R10 R1 K16 + 0x8C280326, // 00A6 GETMET R10 R1 K38 0x7C280200, // 00A7 CALL R10 1 0x7C240200, // 00A8 CALL R9 1 0xA8020004, // 00A9 EXBLK 0 #00AF @@ -12215,21 +11499,21 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x942C020A, // 00AC GETIDX R11 R1 R10 0x9020140B, // 00AD SETMBR R8 R10 R11 0x7001FFFA, // 00AE JMP #00AA - 0x58240012, // 00AF LDCONST R9 K18 + 0x58240027, // 00AF LDCONST R9 K39 0xAC240200, // 00B0 CATCH R9 1 0 0xB0080000, // 00B1 RAISE 2 R0 R0 0x4C240000, // 00B2 LDNIL R9 0x20241009, // 00B3 NE R9 R8 R9 0x78260001, // 00B4 JMPF R9 #00B7 - 0x8C24116F, // 00B5 GETMET R9 R8 K111 + 0x8C241128, // 00B5 GETMET R9 R8 K40 0x7C240200, // 00B6 CALL R9 1 0x4C240000, // 00B7 LDNIL R9 0x60280008, // 00B8 GETGBL R10 G8 - 0x8C2C0314, // 00B9 GETMET R11 R1 K20 - 0x58340070, // 00BA LDCONST R13 K112 + 0x8C2C0308, // 00B9 GETMET R11 R1 K8 + 0x58340029, // 00BA LDCONST R13 K41 0x7C2C0400, // 00BB CALL R11 2 0x7C280200, // 00BC CALL R10 1 - 0x202C1571, // 00BD NE R11 R10 K113 + 0x202C152A, // 00BD NE R11 R10 K42 0x782E0012, // 00BE JMPF R11 #00D2 0xA8020005, // 00BF EXBLK 0 #00C6 0x602C000D, // 00C0 GETGBL R11 G13 @@ -12242,7 +11526,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x70020008, // 00C7 JMP #00D1 0x60340001, // 00C8 GETGBL R13 G1 0x60380018, // 00C9 GETGBL R14 G24 - 0x583C0072, // 00CA LDCONST R15 K114 + 0x583C002B, // 00CA LDCONST R15 K43 0x5C401400, // 00CB MOVE R16 R10 0x5C441600, // 00CC MOVE R17 R11 0x5C481800, // 00CD MOVE R18 R12 @@ -12259,7 +11543,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x60300004, // 00D8 GETGBL R12 G4 0x5C341600, // 00D9 MOVE R13 R11 0x7C300200, // 00DA CALL R12 1 - 0x1C301973, // 00DB EQ R12 R12 K115 + 0x1C30192C, // 00DB EQ R12 R12 K44 0x78320002, // 00DC JMPF R12 #00E0 0x5C301600, // 00DD MOVE R12 R11 0x5C341000, // 00DE MOVE R13 R8 @@ -12270,7 +11554,7 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ 0x70020008, // 00E3 JMP #00ED 0x60340001, // 00E4 GETGBL R13 G1 0x60380018, // 00E5 GETGBL R14 G24 - 0x583C0074, // 00E6 LDCONST R15 K116 + 0x583C002D, // 00E6 LDCONST R15 K45 0x5C401400, // 00E7 MOVE R16 R10 0x5C441600, // 00E8 MOVE R17 R11 0x5C481800, // 00E9 MOVE R18 R12 @@ -12285,6 +11569,163 @@ be_local_closure(class_HASPmota_parse_obj, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: _remove_page +********************************************************************/ +be_local_closure(class_HASPmota__remove_page, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(_remove_page), + &be_const_str_solidified, + ( &(const binstruction[37]) { /* code */ + 0x8C08010F, // 0000 GETMET R2 R0 K15 + 0x7C080200, // 0001 CALL R2 1 + 0x8C080509, // 0002 GETMET R2 R2 K9 + 0x7C080200, // 0003 CALL R2 1 + 0x1C0C0202, // 0004 EQ R3 R1 R2 + 0x780E0008, // 0005 JMPF R3 #000F + 0x8C0C012E, // 0006 GETMET R3 R0 K46 + 0x58140012, // 0007 LDCONST R5 K18 + 0x5818000A, // 0008 LDCONST R6 K10 + 0x581C000A, // 0009 LDCONST R7 K10 + 0x7C0C0800, // 000A CALL R3 4 + 0x4C100000, // 000B LDNIL R4 + 0x1C100604, // 000C EQ R4 R3 R4 + 0x78120000, // 000D JMPF R4 #000F + 0x80000800, // 000E RET 0 + 0x880C0103, // 000F GETMBR R3 R0 K3 + 0x1C0C0601, // 0010 EQ R3 R3 R1 + 0x780E0001, // 0011 JMPF R3 #0014 + 0x880C0104, // 0012 GETMBR R3 R0 K4 + 0x90020603, // 0013 SETMBR R0 K3 R3 + 0x880C0105, // 0014 GETMBR R3 R0 K5 + 0x8C0C0706, // 0015 GETMET R3 R3 K6 + 0x5C140200, // 0016 MOVE R5 R1 + 0x7C0C0400, // 0017 CALL R3 2 + 0x780E0003, // 0018 JMPF R3 #001D + 0x880C0105, // 0019 GETMBR R3 R0 K5 + 0x8C0C072F, // 001A GETMET R3 R3 K47 + 0x5C140200, // 001B MOVE R5 R1 + 0x7C0C0400, // 001C CALL R3 2 + 0x600C0018, // 001D GETGBL R3 G24 + 0x58100030, // 001E LDCONST R4 K48 + 0x5C140200, // 001F MOVE R5 R1 + 0x7C0C0400, // 0020 CALL R3 2 + 0xB8122C00, // 0021 GETNGBL R4 K22 + 0x4C140000, // 0022 LDNIL R5 + 0x90100605, // 0023 SETMBR R4 R3 R5 + 0x80000000, // 0024 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_page_cur_parsing +********************************************************************/ +be_local_closure(class_HASPmota_get_page_cur_parsing, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(get_page_cur_parsing), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040105, // 0000 GETMBR R1 R0 K5 + 0x88080103, // 0001 GETMBR R2 R0 K3 + 0x94040202, // 0002 GETIDX R1 R1 R2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pages_list_sorted +********************************************************************/ +be_local_closure(class_HASPmota_pages_list_sorted, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(pages_list_sorted), + &be_const_str_solidified, + ( &(const binstruction[47]) { /* code */ + 0x60080012, // 0000 GETGBL R2 G18 + 0x7C080000, // 0001 CALL R2 0 + 0x1C0C030A, // 0002 EQ R3 R1 K10 + 0x780E0000, // 0003 JMPF R3 #0005 + 0x88040104, // 0004 GETMBR R1 R0 K4 + 0x600C0010, // 0005 GETGBL R3 G16 + 0x88100105, // 0006 GETMBR R4 R0 K5 + 0x8C100926, // 0007 GETMET R4 R4 K38 + 0x7C100200, // 0008 CALL R4 1 + 0x7C0C0200, // 0009 CALL R3 1 + 0xA8020007, // 000A EXBLK 0 #0013 + 0x5C100600, // 000B MOVE R4 R3 + 0x7C100000, // 000C CALL R4 0 + 0x2014090A, // 000D NE R5 R4 K10 + 0x78160002, // 000E JMPF R5 #0012 + 0x8C140531, // 000F GETMET R5 R2 K49 + 0x5C1C0800, // 0010 MOVE R7 R4 + 0x7C140400, // 0011 CALL R5 2 + 0x7001FFF7, // 0012 JMP #000B + 0x580C0027, // 0013 LDCONST R3 K39 + 0xAC0C0200, // 0014 CATCH R3 1 0 + 0xB0080000, // 0015 RAISE 2 R0 R0 + 0x8C0C0132, // 0016 GETMET R3 R0 K50 + 0x5C140400, // 0017 MOVE R5 R2 + 0x7C0C0400, // 0018 CALL R3 2 + 0x5C080600, // 0019 MOVE R2 R3 + 0x4C0C0000, // 001A LDNIL R3 + 0x1C0C0203, // 001B EQ R3 R1 R3 + 0x780E0000, // 001C JMPF R3 #001E + 0x80040400, // 001D RET 1 R2 + 0x600C000C, // 001E GETGBL R3 G12 + 0x5C100400, // 001F MOVE R4 R2 + 0x7C0C0200, // 0020 CALL R3 1 + 0x00080402, // 0021 ADD R2 R2 R2 + 0x8C100508, // 0022 GETMET R4 R2 K8 + 0x5C180200, // 0023 MOVE R6 R1 + 0x7C100400, // 0024 CALL R4 2 + 0x4C140000, // 0025 LDNIL R5 + 0x1C140805, // 0026 EQ R5 R4 R5 + 0x78160001, // 0027 JMPF R5 #002A + 0x4C140000, // 0028 LDNIL R5 + 0x80040A00, // 0029 RET 1 R5 + 0x00140803, // 002A ADD R5 R4 R3 + 0x04140B11, // 002B SUB R5 R5 K17 + 0x40140805, // 002C CONNECT R5 R4 R5 + 0x94080405, // 002D GETIDX R2 R2 R5 + 0x80040400, // 002E RET 1 R2 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: event_dispatch ********************************************************************/ @@ -12302,38 +11743,38 @@ be_local_closure(class_HASPmota_event_dispatch, /* name */ be_str_weak(event_dispatch), &be_const_str_solidified, ( &(const binstruction[34]) { /* code */ - 0xA40A0200, // 0000 IMPORT R2 K1 - 0x8C0C052C, // 0001 GETMET R3 R2 K44 + 0xA40A2E00, // 0000 IMPORT R2 K23 + 0x8C0C0533, // 0001 GETMET R3 R2 K51 0x5C140200, // 0002 MOVE R5 R1 0x7C0C0400, // 0003 CALL R3 2 - 0x88100175, // 0004 GETMBR R4 R0 K117 + 0x88100134, // 0004 GETMBR R4 R0 K52 0x78120002, // 0005 JMPF R4 #0009 - 0x88100175, // 0006 GETMBR R4 R0 K117 - 0x9012EC03, // 0007 SETMBR R4 K118 R3 + 0x88100134, // 0006 GETMBR R4 R0 K52 + 0x90126A03, // 0007 SETMBR R4 K53 R3 0x70020004, // 0008 JMP #000E - 0xB8120600, // 0009 GETNGBL R4 K3 - 0x8C100977, // 000A GETMET R4 R4 K119 + 0xB8126C00, // 0009 GETNGBL R4 K54 + 0x8C100937, // 000A GETMET R4 R4 K55 0x5C180600, // 000B MOVE R6 R3 0x7C100400, // 000C CALL R4 2 - 0x9002EA04, // 000D SETMBR R0 K117 R4 - 0x88100175, // 000E GETMBR R4 R0 K117 - 0x8C100978, // 000F GETMET R4 R4 K120 + 0x90026804, // 000D SETMBR R0 K52 R4 + 0x88100134, // 000E GETMBR R4 R0 K52 + 0x8C100938, // 000F GETMET R4 R4 K56 0x7C100200, // 0010 CALL R4 1 0x60140009, // 0011 GETGBL R5 G9 0x5C180800, // 0012 MOVE R6 R4 0x7C140200, // 0013 CALL R5 1 - 0x20140B0F, // 0014 NE R5 R5 K15 + 0x20140B0A, // 0014 NE R5 R5 K10 0x7816000A, // 0015 JMPF R5 #0021 - 0x8C140579, // 0016 GETMET R5 R2 K121 + 0x8C140539, // 0016 GETMET R5 R2 K57 0x5C1C0800, // 0017 MOVE R7 R4 0x7C140400, // 0018 CALL R5 2 0x60180004, // 0019 GETGBL R6 G4 0x5C1C0A00, // 001A MOVE R7 R5 0x7C180200, // 001B CALL R6 1 - 0x1C180D08, // 001C EQ R6 R6 K8 + 0x1C180D3A, // 001C EQ R6 R6 K58 0x781A0002, // 001D JMPF R6 #0021 - 0x8C180B28, // 001E GETMET R6 R5 K40 - 0x88200175, // 001F GETMBR R8 R0 K117 + 0x8C180B3B, // 001E GETMET R6 R5 K59 + 0x88200134, // 001F GETMBR R8 R0 K52 0x7C180400, // 0020 CALL R6 2 0x80000000, // 0021 RET 0 }) @@ -12342,71 +11783,671 @@ be_local_closure(class_HASPmota_event_dispatch, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: get_page_cur +********************************************************************/ +be_local_closure(class_HASPmota_get_page_cur, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(get_page_cur), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040105, // 0000 GETMBR R1 R0 K5 + 0x88080104, // 0001 GETMBR R2 R0 K4 + 0x94040202, // 0002 GETIDX R1 R1 R2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: fix_lv_version +********************************************************************/ +be_local_closure(class_HASPmota_fix_lv_version, /* name */ + be_nested_proto( + 6, /* nstack */ + 0, /* argc */ + 12, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(fix_lv_version), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x5800003C, // 0000 LDCONST R0 K60 + 0xA4062E00, // 0001 IMPORT R1 K23 + 0x8C08031E, // 0002 GETMET R2 R1 K30 + 0xB8126C00, // 0003 GETNGBL R4 K54 + 0x5814003D, // 0004 LDCONST R5 K61 + 0x7C080600, // 0005 CALL R2 3 + 0x600C0004, // 0006 GETGBL R3 G4 + 0x5C100400, // 0007 MOVE R4 R2 + 0x7C0C0200, // 0008 CALL R3 1 + 0x200C0702, // 0009 NE R3 R3 K2 + 0x780E0002, // 000A JMPF R3 #000E + 0xB80E6C00, // 000B GETNGBL R3 K54 + 0x54120007, // 000C LDINT R4 8 + 0x900E7A04, // 000D SETMBR R3 K61 R4 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: register_event +********************************************************************/ +be_local_closure(class_HASPmota_register_event, /* name */ + be_nested_proto( + 13, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(event_dispatch), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x68040000, // 0000 GETUPV R1 U0 + 0x8C040300, // 0001 GETMET R1 R1 K0 + 0x5C0C0000, // 0002 MOVE R3 R0 + 0x7C040400, // 0003 CALL R1 2 + 0x80040200, // 0004 RET 1 R1 + }) + ), + }), + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(register_event), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0xA40E7C00, // 0000 IMPORT R3 K62 + 0xA4122E00, // 0001 IMPORT R4 K23 + 0x8814013B, // 0002 GETMBR R5 R0 K59 + 0x4C180000, // 0003 LDNIL R6 + 0x1C140A06, // 0004 EQ R5 R5 R6 + 0x78160003, // 0005 JMPF R5 #000A + 0x8C14073F, // 0006 GETMET R5 R3 K63 + 0x841C0000, // 0007 CLOSURE R7 P0 + 0x7C140400, // 0008 CALL R5 2 + 0x90027605, // 0009 SETMBR R0 K59 R5 + 0x8814031C, // 000A GETMBR R5 R1 K28 + 0x8C180B40, // 000B GETMET R6 R5 K64 + 0x8820013B, // 000C GETMBR R8 R0 K59 + 0x5C240400, // 000D MOVE R9 R2 + 0x8C280933, // 000E GETMET R10 R4 K51 + 0x5C300200, // 000F MOVE R12 R1 + 0x7C280400, // 0010 CALL R10 2 + 0x7C180800, // 0011 CALL R6 4 + 0xA0000000, // 0012 CLOSE R0 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse +********************************************************************/ +be_local_closure(class_HASPmota_parse, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(parse), + &be_const_str_solidified, + ( &(const binstruction[21]) { /* code */ + 0xA40A8200, // 0000 IMPORT R2 K65 + 0x8C0C0542, // 0001 GETMET R3 R2 K66 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x60100004, // 0004 GETGBL R4 G4 + 0x5C140600, // 0005 MOVE R5 R3 + 0x7C100200, // 0006 CALL R4 1 + 0x1C10093A, // 0007 EQ R4 R4 K58 + 0x78120009, // 0008 JMPF R4 #0013 + 0x8C100143, // 0009 GETMET R4 R0 K67 + 0x5C180600, // 000A MOVE R6 R3 + 0x7C100400, // 000B CALL R4 2 + 0x8C100144, // 000C GETMET R4 R0 K68 + 0x5C180600, // 000D MOVE R6 R3 + 0x881C0105, // 000E GETMBR R7 R0 K5 + 0x88200104, // 000F GETMBR R8 R0 K4 + 0x941C0E08, // 0010 GETIDX R7 R7 R8 + 0x7C100600, // 0011 CALL R4 3 + 0x70020000, // 0012 JMP #0014 + 0xB0068B46, // 0013 RAISE 1 K69 K70 + 0x80000000, // 0014 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(class_HASPmota_init, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x8C040147, // 0000 GETMET R1 R0 K71 + 0x7C040200, // 0001 CALL R1 1 + 0xA4069000, // 0002 IMPORT R1 K72 + 0x8C080349, // 0003 GETMET R2 R1 K73 + 0x5810004A, // 0004 LDCONST R4 K74 + 0x7C080400, // 0005 CALL R2 2 + 0x90022602, // 0006 SETMBR R0 K19 R2 + 0x80000000, // 0007 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: start +********************************************************************/ +be_local_closure(class_HASPmota_start, /* name */ + be_nested_proto( + 11, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(start), + &be_const_str_solidified, + ( &(const binstruction[105]) { /* code */ + 0xA40E9600, // 0000 IMPORT R3 K75 + 0x4C100000, // 0001 LDNIL R4 + 0x1C100404, // 0002 EQ R4 R2 R4 + 0x78120000, // 0003 JMPF R4 #0005 + 0x8808014C, // 0004 GETMBR R2 R0 K76 + 0x8C10074D, // 0005 GETMET R4 R3 K77 + 0x5C180400, // 0006 MOVE R6 R2 + 0x7C100400, // 0007 CALL R4 2 + 0x74120002, // 0008 JMPT R4 #000C + 0x00129C02, // 0009 ADD R4 K78 R2 + 0x0010094F, // 000A ADD R4 R4 K79 + 0xB006A004, // 000B RAISE 1 K80 R4 + 0xB8126C00, // 000C GETNGBL R4 K54 + 0x8C100951, // 000D GETMET R4 R4 K81 + 0x7C100200, // 000E CALL R4 1 + 0x60100017, // 000F GETGBL R4 G23 + 0x5C140200, // 0010 MOVE R5 R1 + 0x7C100200, // 0011 CALL R4 1 + 0x9002A404, // 0012 SETMBR R0 K82 R4 + 0xB8126C00, // 0013 GETNGBL R4 K54 + 0x8C100954, // 0014 GETMET R4 R4 K84 + 0x7C100200, // 0015 CALL R4 1 + 0x9002A604, // 0016 SETMBR R0 K83 R4 + 0xB8126C00, // 0017 GETNGBL R4 K54 + 0x8C100956, // 0018 GETMET R4 R4 K86 + 0x7C100200, // 0019 CALL R4 1 + 0x9002AA04, // 001A SETMBR R0 K85 R4 + 0xB8126C00, // 001B GETNGBL R4 K54 + 0x8C100958, // 001C GETMET R4 R4 K88 + 0x7C100200, // 001D CALL R4 1 + 0x9002AE04, // 001E SETMBR R0 K87 R4 + 0xA8020007, // 001F EXBLK 0 #0028 + 0xB8126C00, // 0020 GETNGBL R4 K54 + 0x8C10095A, // 0021 GETMET R4 R4 K90 + 0x5818005B, // 0022 LDCONST R6 K91 + 0x541E000F, // 0023 LDINT R7 16 + 0x7C100600, // 0024 CALL R4 3 + 0x9002B204, // 0025 SETMBR R0 K89 R4 + 0xA8040001, // 0026 EXBLK 1 1 + 0x70020009, // 0027 JMP #0032 + 0xAC100000, // 0028 CATCH R4 0 0 + 0x70020006, // 0029 JMP #0031 + 0xB8126C00, // 002A GETNGBL R4 K54 + 0x8C10095A, // 002B GETMET R4 R4 K90 + 0x5818005C, // 002C LDCONST R6 K92 + 0x541E000D, // 002D LDINT R7 14 + 0x7C100600, // 002E CALL R4 3 + 0x9002B204, // 002F SETMBR R0 K89 R4 + 0x70020000, // 0030 JMP #0032 + 0xB0080000, // 0031 RAISE 2 R0 R0 + 0xB8126C00, // 0032 GETNGBL R4 K54 + 0x8C10095D, // 0033 GETMET R4 R4 K93 + 0x5818000A, // 0034 LDCONST R6 K10 + 0xB81E6C00, // 0035 GETNGBL R7 K54 + 0x8C1C0F5E, // 0036 GETMET R7 R7 K94 + 0x5824005F, // 0037 LDCONST R9 K95 + 0x7C1C0400, // 0038 CALL R7 2 + 0xB8226C00, // 0039 GETNGBL R8 K54 + 0x8C20115E, // 003A GETMET R8 R8 K94 + 0x58280060, // 003B LDCONST R10 K96 + 0x7C200400, // 003C CALL R8 2 + 0x88240152, // 003D GETMBR R9 R0 K82 + 0x88280159, // 003E GETMBR R10 R0 K89 + 0x7C100C00, // 003F CALL R4 6 + 0x88140157, // 0040 GETMBR R5 R0 K87 + 0x8C140B61, // 0041 GETMET R5 R5 K97 + 0x7C140200, // 0042 CALL R5 1 + 0x8C140B62, // 0043 GETMET R5 R5 K98 + 0x5C1C0800, // 0044 MOVE R7 R4 + 0x7C140400, // 0045 CALL R5 2 + 0x88140157, // 0046 GETMBR R5 R0 K87 + 0x8C140B63, // 0047 GETMET R5 R5 K99 + 0x881C0152, // 0048 GETMBR R7 R0 K82 + 0x781E0004, // 0049 JMPF R7 #004F + 0xB81E6C00, // 004A GETNGBL R7 K54 + 0x8C1C0F5E, // 004B GETMET R7 R7 K94 + 0x5824000A, // 004C LDCONST R9 K10 + 0x7C1C0400, // 004D CALL R7 2 + 0x70020003, // 004E JMP #0053 + 0xB81E6C00, // 004F GETNGBL R7 K54 + 0x8C1C0F5E, // 0050 GETMET R7 R7 K94 + 0x58240064, // 0051 LDCONST R9 K100 + 0x7C1C0400, // 0052 CALL R7 2 + 0x5820000A, // 0053 LDCONST R8 K10 + 0x7C140600, // 0054 CALL R5 3 + 0xB8166C00, // 0055 GETNGBL R5 K54 + 0x8C140B65, // 0056 GETMET R5 R5 K101 + 0xB81E6C00, // 0057 GETNGBL R7 K54 + 0x8C1C0F66, // 0058 GETMET R7 R7 K102 + 0x7C1C0200, // 0059 CALL R7 1 + 0x7C140400, // 005A CALL R5 2 + 0xB8166C00, // 005B GETNGBL R5 K54 + 0x8C140B66, // 005C GETMET R5 R5 K102 + 0x7C140200, // 005D CALL R5 1 + 0x8C140B67, // 005E GETMET R5 R5 K103 + 0x581C000A, // 005F LDCONST R7 K10 + 0x5820000A, // 0060 LDCONST R8 K10 + 0x7C140600, // 0061 CALL R5 3 + 0x60140013, // 0062 GETGBL R5 G19 + 0x7C140000, // 0063 CALL R5 0 + 0x90020A05, // 0064 SETMBR R0 K5 R5 + 0x8C140168, // 0065 GETMET R5 R0 K104 + 0x5C1C0400, // 0066 MOVE R7 R2 + 0x7C140400, // 0067 CALL R5 2 + 0x80000000, // 0068 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: page_dir_to +********************************************************************/ +be_local_closure(class_HASPmota_page_dir_to, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(page_dir_to), + &be_const_str_solidified, + ( &(const binstruction[32]) { /* code */ + 0x8C080110, // 0000 GETMET R2 R0 K16 + 0x5810000A, // 0001 LDCONST R4 K10 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x1C0C0403, // 0004 EQ R3 R2 R3 + 0x780E0000, // 0005 JMPF R3 #0007 + 0x80061400, // 0006 RET 1 K10 + 0x600C000C, // 0007 GETGBL R3 G12 + 0x5C100400, // 0008 MOVE R4 R2 + 0x7C0C0200, // 0009 CALL R3 1 + 0x18100711, // 000A LE R4 R3 K17 + 0x78120000, // 000B JMPF R4 #000D + 0x80061400, // 000C RET 1 K10 + 0x1C100769, // 000D EQ R4 R3 K105 + 0x78120000, // 000E JMPF R4 #0010 + 0x80062200, // 000F RET 1 K17 + 0x8C100508, // 0010 GETMET R4 R2 K8 + 0x5C180200, // 0011 MOVE R6 R1 + 0x7C100400, // 0012 CALL R4 2 + 0x4C140000, // 0013 LDNIL R5 + 0x1C140805, // 0014 EQ R5 R4 R5 + 0x78160000, // 0015 JMPF R5 #0017 + 0x80061400, // 0016 RET 1 K10 + 0x00140711, // 0017 ADD R5 R3 K17 + 0x0C140B69, // 0018 DIV R5 R5 K105 + 0x18140805, // 0019 LE R5 R4 R5 + 0x78160001, // 001A JMPF R5 #001D + 0x80062200, // 001B RET 1 K17 + 0x70020001, // 001C JMP #001F + 0x5415FFFE, // 001D LDINT R5 -1 + 0x80040A00, // 001E RET 1 R5 + 0x80000000, // 001F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: do_action +********************************************************************/ +be_local_closure(class_HASPmota_do_action, /* name */ + be_nested_proto( + 6, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(do_action), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0xB80E6C00, // 0000 GETNGBL R3 K54 + 0x880C076A, // 0001 GETMBR R3 R3 K106 + 0x200C0403, // 0002 NE R3 R2 R3 + 0x780E0000, // 0003 JMPF R3 #0005 + 0x80000600, // 0004 RET 0 + 0x8C0C012E, // 0005 GETMET R3 R0 K46 + 0x8814036B, // 0006 GETMBR R5 R1 K107 + 0x7C0C0400, // 0007 CALL R3 2 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: _load +********************************************************************/ +be_local_closure(class_HASPmota__load, /* name */ + be_nested_proto( + 14, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(_load), + &be_const_str_solidified, + ( &(const binstruction[99]) { /* code */ + 0xA40AD800, // 0000 IMPORT R2 K108 + 0xA40E8200, // 0001 IMPORT R3 K65 + 0x60100011, // 0002 GETGBL R4 G17 + 0x5C140200, // 0003 MOVE R5 R1 + 0x5818006D, // 0004 LDCONST R6 K109 + 0x7C100400, // 0005 CALL R4 2 + 0x8C14096E, // 0006 GETMET R5 R4 K110 + 0x7C140200, // 0007 CALL R5 1 + 0x8C18096F, // 0008 GETMET R6 R4 K111 + 0x7C180200, // 0009 CALL R6 1 + 0x8C180570, // 000A GETMET R6 R2 K112 + 0x5C200A00, // 000B MOVE R8 R5 + 0x58240071, // 000C LDCONST R9 K113 + 0x7C180600, // 000D CALL R6 3 + 0x4C100000, // 000E LDNIL R4 + 0x4C140000, // 000F LDNIL R5 + 0x601C000C, // 0010 GETGBL R7 G12 + 0x5C200C00, // 0011 MOVE R8 R6 + 0x7C1C0200, // 0012 CALL R7 1 + 0x241C0F0A, // 0013 GT R7 R7 K10 + 0x781E0039, // 0014 JMPF R7 #004F + 0x8C1C0742, // 0015 GETMET R7 R3 K66 + 0x94240D0A, // 0016 GETIDX R9 R6 K10 + 0x7C1C0400, // 0017 CALL R7 2 + 0x60200004, // 0018 GETGBL R8 G4 + 0x5C240E00, // 0019 MOVE R9 R7 + 0x7C200200, // 001A CALL R8 1 + 0x1C20113A, // 001B EQ R8 R8 K58 + 0x7822001B, // 001C JMPF R8 #0039 + 0xB822E400, // 001D GETNGBL R8 K114 + 0x8C201173, // 001E GETMET R8 R8 K115 + 0x542A0003, // 001F LDINT R10 4 + 0x7C200400, // 0020 CALL R8 2 + 0x78220007, // 0021 JMPF R8 #002A + 0xB822E400, // 0022 GETNGBL R8 K114 + 0x8C201174, // 0023 GETMET R8 R8 K116 + 0x60280018, // 0024 GETGBL R10 G24 + 0x582C0075, // 0025 LDCONST R11 K117 + 0x94300D0A, // 0026 GETIDX R12 R6 K10 + 0x7C280400, // 0027 CALL R10 2 + 0x542E0003, // 0028 LDINT R11 4 + 0x7C200600, // 0029 CALL R8 3 + 0x8C200143, // 002A GETMET R8 R0 K67 + 0x5C280E00, // 002B MOVE R10 R7 + 0x7C200400, // 002C CALL R8 2 + 0x88200105, // 002D GETMBR R8 R0 K5 + 0x4C240000, // 002E LDNIL R9 + 0x1C201009, // 002F EQ R8 R8 R9 + 0x78220000, // 0030 JMPF R8 #0032 + 0xB0068B76, // 0031 RAISE 1 K69 K118 + 0x8C200144, // 0032 GETMET R8 R0 K68 + 0x5C280E00, // 0033 MOVE R10 R7 + 0x882C0105, // 0034 GETMBR R11 R0 K5 + 0x88300103, // 0035 GETMBR R12 R0 K3 + 0x942C160C, // 0036 GETIDX R11 R11 R12 + 0x7C200600, // 0037 CALL R8 3 + 0x70020010, // 0038 JMP #004A + 0x6020000C, // 0039 GETGBL R8 G12 + 0x8C240577, // 003A GETMET R9 R2 K119 + 0x942C0D0A, // 003B GETIDX R11 R6 K10 + 0x58300078, // 003C LDCONST R12 K120 + 0x58340079, // 003D LDCONST R13 K121 + 0x7C240800, // 003E CALL R9 4 + 0x7C200200, // 003F CALL R8 1 + 0x2420110A, // 0040 GT R8 R8 K10 + 0x78220007, // 0041 JMPF R8 #004A + 0xB822E400, // 0042 GETNGBL R8 K114 + 0x8C201174, // 0043 GETMET R8 R8 K116 + 0x60280018, // 0044 GETGBL R10 G24 + 0x582C007A, // 0045 LDCONST R11 K122 + 0x94300D0A, // 0046 GETIDX R12 R6 K10 + 0x7C280400, // 0047 CALL R10 2 + 0x582C0069, // 0048 LDCONST R11 K105 + 0x7C200600, // 0049 CALL R8 3 + 0x4C1C0000, // 004A LDNIL R7 + 0x8C200D2F, // 004B GETMET R8 R6 K47 + 0x5828000A, // 004C LDCONST R10 K10 + 0x7C200400, // 004D CALL R8 2 + 0x7001FFC0, // 004E JMP #0010 + 0x4C180000, // 004F LDNIL R6 + 0x8C1C0110, // 0050 GETMET R7 R0 K16 + 0x4C240000, // 0051 LDNIL R9 + 0x7C1C0400, // 0052 CALL R7 2 + 0x6020000C, // 0053 GETGBL R8 G12 + 0x5C240E00, // 0054 MOVE R9 R7 + 0x7C200200, // 0055 CALL R8 1 + 0x1C20110A, // 0056 EQ R8 R8 K10 + 0x78220000, // 0057 JMPF R8 #0059 + 0xB0068B7B, // 0058 RAISE 1 K69 K123 + 0x94200F0A, // 0059 GETIDX R8 R7 K10 + 0x90020808, // 005A SETMBR R0 K4 R8 + 0x88200105, // 005B GETMBR R8 R0 K5 + 0x88240104, // 005C GETMBR R9 R0 K4 + 0x94201009, // 005D GETIDX R8 R8 R9 + 0x8C201115, // 005E GETMET R8 R8 K21 + 0x5828000A, // 005F LDCONST R10 K10 + 0x582C000A, // 0060 LDCONST R11 K10 + 0x7C200600, // 0061 CALL R8 3 + 0x80000000, // 0062 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: sort +********************************************************************/ +be_local_closure(class_HASPmota_sort, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 12, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(sort), + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0x5804003C, // 0000 LDCONST R1 K60 + 0x60080010, // 0001 GETGBL R2 G16 + 0x600C000C, // 0002 GETGBL R3 G12 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C0C0200, // 0004 CALL R3 1 + 0x040C0711, // 0005 SUB R3 R3 K17 + 0x400E2203, // 0006 CONNECT R3 K17 R3 + 0x7C080200, // 0007 CALL R2 1 + 0xA8020010, // 0008 EXBLK 0 #001A + 0x5C0C0400, // 0009 MOVE R3 R2 + 0x7C0C0000, // 000A CALL R3 0 + 0x94100003, // 000B GETIDX R4 R0 R3 + 0x5C140600, // 000C MOVE R5 R3 + 0x24180B0A, // 000D GT R6 R5 K10 + 0x781A0008, // 000E JMPF R6 #0018 + 0x04180B11, // 000F SUB R6 R5 K17 + 0x94180006, // 0010 GETIDX R6 R0 R6 + 0x24180C04, // 0011 GT R6 R6 R4 + 0x781A0004, // 0012 JMPF R6 #0018 + 0x04180B11, // 0013 SUB R6 R5 K17 + 0x94180006, // 0014 GETIDX R6 R0 R6 + 0x98000A06, // 0015 SETIDX R0 R5 R6 + 0x04140B11, // 0016 SUB R5 R5 K17 + 0x7001FFF4, // 0017 JMP #000D + 0x98000A04, // 0018 SETIDX R0 R5 R4 + 0x7001FFEE, // 0019 JMP #0009 + 0x58080027, // 001A LDCONST R2 K39 + 0xAC080200, // 001B CATCH R2 1 0 + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x80040000, // 001D RET 1 R0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified class: HASPmota ********************************************************************/ be_local_class(HASPmota, - 10, + 11, NULL, - be_nested_map(57, + be_nested_map(59, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(re_page_target, 4), be_const_var(7) }, - { be_const_key_weak(lvh_line, -1), be_const_class(be_class_lvh_line) }, - { be_const_key_weak(lvh_pages, -1), be_const_var(5) }, - { be_const_key_weak(lvh_dropdown_list, -1), be_const_class(be_class_lvh_dropdown_list) }, - { be_const_key_weak(lvh_dropdown, -1), be_const_class(be_class_lvh_dropdown) }, - { be_const_key_weak(lvh_label, 53), be_const_class(be_class_lvh_label) }, - { be_const_key_weak(lvh_spinner, -1), be_const_class(be_class_lvh_spinner) }, - { be_const_key_weak(lvh_scale, -1), be_const_class(be_class_lvh_scale) }, - { be_const_key_weak(lvh_obj, -1), be_const_class(be_class_lvh_obj) }, - { be_const_key_weak(event_dispatch, -1), be_const_closure(class_HASPmota_event_dispatch_closure) }, - { be_const_key_weak(parse, 2), be_const_closure(class_HASPmota_parse_closure) }, - { be_const_key_weak(scr, -1), be_const_var(3) }, - { be_const_key_weak(lvh_msgbox, 25), be_const_class(be_class_lvh_msgbox) }, - { be_const_key_weak(lvh_fixed, -1), be_const_class(be_class_lvh_fixed) }, - { be_const_key_weak(lvh_checkbox, -1), be_const_class(be_class_lvh_checkbox) }, - { be_const_key_weak(hres, 49), be_const_var(1) }, - { be_const_key_weak(lvh_page, 46), be_const_class(be_class_lvh_page) }, - { be_const_key_weak(sort, -1), be_const_static_closure(class_HASPmota_sort_closure) }, - { be_const_key_weak(dark, 32), be_const_var(0) }, - { be_const_key_weak(lvh_scale_line, -1), be_const_class(be_class_lvh_scale_line) }, - { be_const_key_weak(get_page_cur, -1), be_const_closure(class_HASPmota_get_page_cur_closure) }, - { be_const_key_weak(event, -1), be_const_var(8) }, - { be_const_key_weak(lvh_led, -1), be_const_class(be_class_lvh_led) }, - { be_const_key_weak(parse_page, -1), be_const_closure(class_HASPmota_parse_page_closure) }, + { be_const_key_weak(lvh_dropdown_list, 50), be_const_class(be_class_lvh_dropdown_list) }, + { be_const_key_weak(lvh_line, 19), be_const_class(be_class_lvh_line) }, { be_const_key_weak(r16, -1), be_const_var(4) }, - { be_const_key_weak(event_cb, 13), be_const_var(9) }, - { be_const_key_weak(lvh_btn, -1), be_const_class(be_class_lvh_btn) }, - { be_const_key_weak(lvh_bar, -1), be_const_class(be_class_lvh_bar) }, - { be_const_key_weak(lvh_scale_section, 38), be_const_class(be_class_lvh_scale_section) }, - { be_const_key_weak(do_action, -1), be_const_closure(class_HASPmota_do_action_closure) }, - { be_const_key_weak(lvh_root, -1), be_const_class(be_class_lvh_root) }, - { be_const_key_weak(_remove_page, 43), be_const_closure(class_HASPmota__remove_page_closure) }, - { be_const_key_weak(lvh_roller, -1), be_const_class(be_class_lvh_roller) }, - { be_const_key_weak(lvh_img, 16), be_const_class(be_class_lvh_img) }, - { be_const_key_weak(lvh_qrcode, 35), be_const_class(be_class_lvh_qrcode) }, - { be_const_key_weak(lvh_span, -1), be_const_class(be_class_lvh_span) }, - { be_const_key_weak(page_dir_to, -1), be_const_closure(class_HASPmota_page_dir_to_closure) }, - { be_const_key_weak(def_templ_name, -1), be_nested_str_weak(pages_X2Ejsonl) }, - { be_const_key_weak(lvh_switch, -1), be_const_class(be_class_lvh_switch) }, - { be_const_key_weak(lvh_slider, -1), be_const_class(be_class_lvh_slider) }, { be_const_key_weak(page_show, -1), be_const_closure(class_HASPmota_page_show_closure) }, - { be_const_key_weak(start, -1), be_const_closure(class_HASPmota_start_closure) }, - { be_const_key_weak(pages_list_sorted, 34), be_const_closure(class_HASPmota_pages_list_sorted_closure) }, - { be_const_key_weak(_load, -1), be_const_closure(class_HASPmota__load_closure) }, - { be_const_key_weak(lvh_scr, -1), be_const_class(be_class_lvh_scr) }, - { be_const_key_weak(lvh_chart, 31), be_const_class(be_class_lvh_chart) }, - { be_const_key_weak(register_event, -1), be_const_closure(class_HASPmota_register_event_closure) }, - { be_const_key_weak(lvh_btnmatrix, 18), be_const_class(be_class_lvh_btnmatrix) }, - { be_const_key_weak(lvh_cpicker, 17), be_const_class(be_class_lvh_cpicker) }, - { be_const_key_weak(lvh_flex, -1), be_const_class(be_class_lvh_flex) }, - { be_const_key_weak(parse_obj, 8), be_const_closure(class_HASPmota_parse_obj_closure) }, - { be_const_key_weak(init, 12), be_const_closure(class_HASPmota_init_closure) }, - { be_const_key_weak(vres, 9), be_const_var(2) }, + { be_const_key_weak(parse_page, -1), be_const_closure(class_HASPmota_parse_page_closure) }, + { be_const_key_weak(sort, 12), be_const_static_closure(class_HASPmota_sort_closure) }, + { be_const_key_weak(event_dispatch, -1), be_const_closure(class_HASPmota_event_dispatch_closure) }, + { be_const_key_weak(lvh_roller, 10), be_const_class(be_class_lvh_roller) }, + { be_const_key_weak(lvh_page_cur_idx_parsing, -1), be_const_var(7) }, + { be_const_key_weak(hres, -1), be_const_var(1) }, { be_const_key_weak(lvh_page_cur_idx, -1), be_const_var(6) }, - { be_const_key_weak(fix_lv_version, 7), be_const_static_closure(class_HASPmota_fix_lv_version_closure) }, + { be_const_key_weak(_remove_page, 13), be_const_closure(class_HASPmota__remove_page_closure) }, + { be_const_key_weak(lvh_chart, -1), be_const_class(be_class_lvh_chart) }, + { be_const_key_weak(_load, 16), be_const_closure(class_HASPmota__load_closure) }, + { be_const_key_weak(dark, 5), be_const_var(0) }, + { be_const_key_weak(parse_obj, 6), be_const_closure(class_HASPmota_parse_obj_closure) }, + { be_const_key_weak(lvh_msgbox, -1), be_const_class(be_class_lvh_msgbox) }, + { be_const_key_weak(get_page_cur, 29), be_const_closure(class_HASPmota_get_page_cur_closure) }, + { be_const_key_weak(event, -1), be_const_var(9) }, + { be_const_key_weak(scr, 51), be_const_var(3) }, + { be_const_key_weak(vres, -1), be_const_var(2) }, + { be_const_key_weak(lvh_scale, -1), be_const_class(be_class_lvh_scale) }, + { be_const_key_weak(register_event, 24), be_const_closure(class_HASPmota_register_event_closure) }, { be_const_key_weak(lvh_arc, -1), be_const_class(be_class_lvh_arc) }, + { be_const_key_weak(do_action, 23), be_const_closure(class_HASPmota_do_action_closure) }, + { be_const_key_weak(lvh_dropdown, -1), be_const_class(be_class_lvh_dropdown) }, + { be_const_key_weak(lvh_fixed, -1), be_const_class(be_class_lvh_fixed) }, + { be_const_key_weak(re_page_target, 43), be_const_var(8) }, + { be_const_key_weak(lvh_slider, -1), be_const_class(be_class_lvh_slider) }, + { be_const_key_weak(fix_lv_version, -1), be_const_static_closure(class_HASPmota_fix_lv_version_closure) }, + { be_const_key_weak(lvh_checkbox, -1), be_const_class(be_class_lvh_checkbox) }, + { be_const_key_weak(parse, 47), be_const_closure(class_HASPmota_parse_closure) }, + { be_const_key_weak(lvh_pages, -1), be_const_var(5) }, + { be_const_key_weak(lvh_btn, -1), be_const_class(be_class_lvh_btn) }, + { be_const_key_weak(start, -1), be_const_closure(class_HASPmota_start_closure) }, + { be_const_key_weak(lvh_root, -1), be_const_class(be_class_lvh_root) }, + { be_const_key_weak(lvh_page, -1), be_const_class(be_class_lvh_page) }, + { be_const_key_weak(pages_list_sorted, 26), be_const_closure(class_HASPmota_pages_list_sorted_closure) }, + { be_const_key_weak(lvh_qrcode, 45), be_const_class(be_class_lvh_qrcode) }, + { be_const_key_weak(lvh_label, -1), be_const_class(be_class_lvh_label) }, + { be_const_key_weak(lvh_scr, 28), be_const_class(be_class_lvh_scr) }, + { be_const_key_weak(lvh_img, 27), be_const_class(be_class_lvh_img) }, + { be_const_key_weak(get_page_cur_parsing, 30), be_const_closure(class_HASPmota_get_page_cur_parsing_closure) }, + { be_const_key_weak(page_dir_to, 49), be_const_closure(class_HASPmota_page_dir_to_closure) }, + { be_const_key_weak(lvh_obj, -1), be_const_class(be_class_lvh_obj) }, + { be_const_key_weak(lvh_switch, -1), be_const_class(be_class_lvh_switch) }, + { be_const_key_weak(lvh_bar, -1), be_const_class(be_class_lvh_bar) }, + { be_const_key_weak(init, -1), be_const_closure(class_HASPmota_init_closure) }, + { be_const_key_weak(lvh_btnmatrix, -1), be_const_class(be_class_lvh_btnmatrix) }, + { be_const_key_weak(lvh_spinner, 52), be_const_class(be_class_lvh_spinner) }, + { be_const_key_weak(lvh_led, 3), be_const_class(be_class_lvh_led) }, + { be_const_key_weak(lvh_flex, 57), be_const_class(be_class_lvh_flex) }, { be_const_key_weak(lvh_spangroup, -1), be_const_class(be_class_lvh_spangroup) }, + { be_const_key_weak(lvh_span, -1), be_const_class(be_class_lvh_span) }, + { be_const_key_weak(def_templ_name, 9), be_nested_str_weak(pages_X2Ejsonl) }, + { be_const_key_weak(lvh_scale_section, 7), be_const_class(be_class_lvh_scale_section) }, + { be_const_key_weak(event_cb, -1), be_const_var(10) }, + { be_const_key_weak(lvh_scale_line, -1), be_const_class(be_class_lvh_scale_line) }, + { be_const_key_weak(lvh_cpicker, -1), be_const_class(be_class_lvh_cpicker) }, })), be_str_weak(HASPmota) ); From 9c24258530b60a79d1b121b9815d83ba26f0b555 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 13:09:35 +0200 Subject: [PATCH 020/205] disable ir (#22321) --- tasmota/include/tasmota_configurations.h | 32 +++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h index 2cecc2d46..03aa2828b 100644 --- a/tasmota/include/tasmota_configurations.h +++ b/tasmota/include/tasmota_configurations.h @@ -1029,21 +1029,23 @@ #define SEND_PRONTO false // Exclude PRONTO protocol #else #define _IR_ENABLE_DEFAULT_ false // disable all protocols by default - // below are the default IR protocols - #define DECODE_HASH true - #ifdef USE_IR_SEND_NEC - #define SEND_NEC true // Support IRsend NEC protocol - #define DECODE_NEC true // Support IRreceive NEC protocol - #endif - #ifdef USE_IR_SEND_RC5 - #define SEND_RC5 true // Support IRsend Philips RC5 protocol - #define DECODE_RC5 true // Support IRreceive Philips RC5 protocol - #endif - #ifdef USE_IR_SEND_RC6 - #define SEND_RC6 true // Support IRsend Philips RC6 protocol - #define DECODE_RC6 true // Support IRreceive Philips RC6 protocol - #endif -#endif + #ifdef USE_IR_REMOTE + // below are the default IR protocols + #define DECODE_HASH true + #ifdef USE_IR_SEND_NEC + #define SEND_NEC true // Support IRsend NEC protocol + #define DECODE_NEC true // Support IRreceive NEC protocol + #endif // USE_IR_SEND_NEC + #ifdef USE_IR_SEND_RC5 + #define SEND_RC5 true // Support IRsend Philips RC5 protocol + #define DECODE_RC5 true // Support IRreceive Philips RC5 protocol + #endif // USE_IR_SEND_RC5 + #ifdef USE_IR_SEND_RC6 + #define SEND_RC6 true // Support IRsend Philips RC6 protocol + #define DECODE_RC6 true // Support IRreceive Philips RC6 protocol + #endif // USE_IR_SEND_RC6 + #endif // USE_IR_REMOTE +#endif // USE_IR_REMOTE_FULL /*********************************************************************************************\ * Mandatory defines satisfying disabled defines From 923ed91c9cd4c4fd78f3f688585af466a83cb444 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 19 Oct 2024 14:06:42 +0200 Subject: [PATCH 021/205] optimize env `tasmota32-zbbrdgpro` (#22323) * remove IR Remote from zigbee bridgg * remove shutters support * add lib ignores to zigbee bridge env * remove ENERGY_SENSOR from zigbee bridge 32 env --- platformio_tasmota_env32.ini | 7 +++++++ tasmota/include/tasmota_configurations_ESP32.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 16f51e842..f5dc5931a 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -257,6 +257,8 @@ build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_IR -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-ir.bin"' lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_ssl +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP [env:tasmota32-zbbrdgpro] extends = env:tasmota32_base @@ -271,6 +273,11 @@ custom_files_upload = ${env:tasmota32_base.custom_files_upload} tasmota/berry/zigbee/sonoff_zb_pro_flasher.be tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20220219.hex lib_extra_dirs = lib/lib_basic, lib/lib_ssl, lib/libesp32 +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + IRremoteESP8266 + TasmotaModbus + ESP Mail Client custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 CONFIG_D0WD_PSRAM_CS_IO=18 diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 21343be87..07973b225 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -515,6 +515,9 @@ #define USE_ENHANCED_GUI_WIFI_SCAN +#undef USE_ENERGY_SENSOR // Disable support for energy sensors +#undef USE_SHUTTER // Disable support for shutter +#undef USE_IR_REMOTE // Disable support for IR Remote #undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) #undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer (+2k code) #undef USE_SONOFF_IFAN // Disable support for Sonoff iFan02 and iFan03 (+2k code) From 7ea96eb0054530e64a1303fcc0cfa8ccbf552124 Mon Sep 17 00:00:00 2001 From: btsimonh Date: Sun, 20 Oct 2024 11:13:07 +0100 Subject: [PATCH 022/205] EQ3 TRV firmware version 1.46 fails if the default true is used in ->subscribe on the notify characteristic. (#22328) So pass false always - then it works with both new and old EQ3 firmware. --- .../tasmota_xdrv_driver/xdrv_79_esp32_ble.ino | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino index 763ffc477..bb3cd2caa 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino @@ -1905,12 +1905,27 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: got notify characteristic")); #endif op->notifylen = 0; + bool response = false; + + /* although it FEELS like this would do the job, it does not for EQ3. + // when SHOULD we pass the default true? Is it just that EQ3 is a bad BLE implementation? + bool response = true; + if (pNCharacteristic->canWriteNoResponse()){ + response = false; + } + */ + uint8_t props = pNCharacteristic->getProperties(); +#ifdef BLE_ESP32_DEBUG + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: characteristic props 0x%02X"), props); +#endif + if(pNCharacteristic->canNotify()) { uint64_t now = esp_timer_get_time(); op->notifytimer = now; - if(pNCharacteristic->subscribe(true, BLE_ESP32::BLEGenNotifyCB)) { + + if(pNCharacteristic->subscribe(true, BLE_ESP32::BLEGenNotifyCB, response)) { #ifdef BLE_ESP32_DEBUG - if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: subscribe for notify")); + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: subscribe for notify - resp %d"), response? 1:0); #endif // this will get changed to read or write, // but here in case it's notify only (can that happen?) @@ -1918,7 +1933,7 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe waitNotify = true; } else { #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: failed subscribe for notify")); + AddLog(LOG_LEVEL_ERROR,PSTR("BLE: failed subscribe for notify - resp %d"), response? 1:0); #endif newstate = GEN_STATE_FAILED_NOTIFY; op->notifytimer = 0L; @@ -1927,15 +1942,15 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe if(pNCharacteristic->canIndicate()) { uint64_t now = esp_timer_get_time(); op->notifytimer = now; - if(pNCharacteristic->subscribe(false, BLE_ESP32::BLEGenNotifyCB)) { + if(pNCharacteristic->subscribe(false, BLE_ESP32::BLEGenNotifyCB, response)) { #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: subscribe for indicate")); + AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: subscribe for indicate - resp %d"), response? 1:0); #endif notifystate = GEN_STATE_WAITINDICATE; waitNotify = true; } else { #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: failed subscribe for indicate")); + AddLog(LOG_LEVEL_ERROR,PSTR("BLE: failed subscribe for indicate - resp %d"), response? 1:0); #endif newstate = GEN_STATE_FAILED_INDICATE; op->notifytimer = 0L; From bd88ddc56d0be5efd0c652ad565604d0069d1969 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:09:58 +0200 Subject: [PATCH 023/205] Update changelogs --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66fe25df5..b19e01d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file. - HASPmota support for page delete and object updates (#22311) ### Fixed +- EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic (#22328) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 741bbc3d1..2403e2b60 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -126,5 +126,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed +- EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) ### Removed From f6699b529c08816331e923bbbcc2d7ca6c634bbc Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Sun, 20 Oct 2024 17:37:29 +0200 Subject: [PATCH 024/205] Translate BLE (#22331) --- tasmota/language/af_AF.h | 8 ++++++++ tasmota/language/bg_BG.h | 8 ++++++++ tasmota/language/ca_AD.h | 8 ++++++++ tasmota/language/cs_CZ.h | 8 ++++++++ tasmota/language/de_DE.h | 8 ++++++++ tasmota/language/el_GR.h | 8 ++++++++ tasmota/language/en_GB.h | 8 ++++++++ tasmota/language/es_ES.h | 8 ++++++++ tasmota/language/fr_FR.h | 8 ++++++++ tasmota/language/fy_NL.h | 8 ++++++++ tasmota/language/he_HE.h | 8 ++++++++ tasmota/language/hu_HU.h | 8 ++++++++ tasmota/language/it_IT.h | 8 ++++++++ tasmota/language/ko_KO.h | 8 ++++++++ tasmota/language/nl_NL.h | 8 ++++++++ tasmota/language/pl_PL.h | 8 ++++++++ tasmota/language/pt_BR.h | 8 ++++++++ tasmota/language/pt_PT.h | 8 ++++++++ tasmota/language/ro_RO.h | 8 ++++++++ tasmota/language/ru_RU.h | 8 ++++++++ tasmota/language/sk_SK.h | 8 ++++++++ tasmota/language/sv_SE.h | 8 ++++++++ tasmota/language/tr_TR.h | 8 ++++++++ tasmota/language/uk_UA.h | 8 ++++++++ tasmota/language/vi_VN.h | 8 ++++++++ tasmota/language/zh_CN.h | 8 ++++++++ tasmota/language/zh_TW.h | 8 ++++++++ tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino | 7 +------ 28 files changed, 217 insertions(+), 6 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 9b58f716b..0c55d7f18 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor besig" #define D_SENSOR_CRC_ERROR "Sensor CRC fout" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index aab2d5396..78ba90ca2 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Датчикът DS18x20 е зает" #define D_SENSOR_CRC_ERROR "Датчик DS18x20 - грешка CRC" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index 8f8a6c9e0..894362945 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor busy" #define D_SENSOR_CRC_ERROR "Sensor CRC error" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 4263ddbd2..4df9b761b 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor DS18x20 obsazen" #define D_SENSOR_CRC_ERROR "Sensor DS18x20 chyba CRC" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index c8de7e1f0..77f0f5bd3 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "BLE-Einstellungen" +#define D_BLE_PARAMETERS "Bluetooth-Einstellungen" +#define D_MQTT_BLE_ENABLE "Bluetooth aktivieren" +#define D_MQTT_BLE_ACTIVESCAN "Aktiv scannen (*)" +#define D_BLE_DEVICES "Erkannte Geräte" +#define D_BLE_REMARK "Mit (*) markierte Geräte werden nicht gespeichert." + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor beschäftigt" #define D_SENSOR_CRC_ERROR "Sensor CRC-Fehler" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 62fd01a65..4915b82ff 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Ο αισθητήρας είναι απασχολημένος" #define D_SENSOR_CRC_ERROR "Σφάλμα CRC αισθητήρα" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 05700a230..edd3370dd 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor busy" #define D_SENSOR_CRC_ERROR "Sensor CRC error" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index d0a4cc72c..77eb3c295 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor ocupado" #define D_SENSOR_CRC_ERROR "Error CRC del Sensor" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 9b363c57c..41dd53979 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Capteur occupé" #define D_SENSOR_CRC_ERROR "Erreur CRC capteur" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 7991bac52..2fe8b6eec 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor drok" #define D_SENSOR_CRC_ERROR "Sensor CRC flater" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 48a7ef17d..97615d7b7 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "שרת עסוק" #define D_SENSOR_CRC_ERROR "בחיישן CRC שגיאת" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 89d96304d..e9370b023 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Szenzor foglalt" #define D_SENSOR_CRC_ERROR "Szenzor CRC hiba" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 3364dc3f4..9da62b200 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (ibdrida)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Regolazione automatica (ibrida)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensore occupato" #define D_SENSOR_CRC_ERROR "Errore CRC sensore" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index f545eb38f..a4208da31 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "센서가 사용 중" #define D_SENSOR_CRC_ERROR "센서 CRC 에러" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 7f5fecdb4..6e0a38287 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor bezet" #define D_SENSOR_CRC_ERROR "Sensor CRC fout" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index ae79d7a4e..56d95235d 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Czujnik zajęty" #define D_SENSOR_CRC_ERROR "Błąd CRC czujnika" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 0b3fce6fd..5d21edca2 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor ocupado" #define D_SENSOR_CRC_ERROR "Erro CRC sensor" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index b9beddd84..3108fd24c 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor ocupado" #define D_SENSOR_CRC_ERROR "Erro no CRC do sensor" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index b41043a2d..eb5042cad 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Senzor ocupat" #define D_SENSOR_CRC_ERROR "Eroare senzor CRC" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index a7ff3e0fc..a6180994a 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -573,6 +573,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Датчик DS18x20 занят" #define D_SENSOR_CRC_ERROR "Датчик DS18x20 - ошибка CRC" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index d65869917..2affb9750 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor DS18x20 obsadený" #define D_SENSOR_CRC_ERROR "Sensor DS18x20 chyba CRC" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index de5fb68b2..486d4939a 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensor upptagen" #define D_SENSOR_CRC_ERROR "Sensor CRC-fel" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 23dc61fd1..2da473200 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Sensör başgül" #define D_SENSOR_CRC_ERROR "Sensor CRC hatası" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index fba2ed0c5..bb2210680 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Давач DS18x20 зайнятий" #define D_SENSOR_CRC_ERROR "Давач DS18x20 - помилка CRC" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 106312501..ef176f815 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Cảm biến đang bận" #define D_SENSOR_CRC_ERROR "Cảm biến CRC lỗi" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index b3218a523..a11e94e57 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "传感器正忙" #define D_SENSOR_CRC_ERROR "传感器 CRC 校验错误" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 2028d0865..b2c08d951 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -572,6 +572,14 @@ #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "Configure BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_MQTT_BLE_ENABLE "Enable Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "感應器忙碌中" #define D_SENSOR_CRC_ERROR "感應器 CRC 校驗錯誤" diff --git a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino index bb3cd2caa..2c5aa816d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino @@ -3465,11 +3465,6 @@ std::string BLETriggerResponse(generic_sensor_t *toSend){ #ifdef USE_WEBSERVER #define WEB_HANDLE_BLE "ble" -#define D_CONFIGURE_BLE "Configure BLE" -#define D_BLE_PARAMETERS "Bluetooth Settings" -#define D_MQTT_BLE_ENABLE "Enable Bluetooth" -#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" -#define D_BLE_DEVICES "Devices Seen" const char HTTP_BTN_MENU_BLE[] PROGMEM = "

"; @@ -3479,7 +3474,7 @@ const char HTTP_FORM_BLE[] PROGMEM = "
" "

" "

" - "

items marked (*) are not stored in config

"; + "

" D_BLE_REMARK "

"; const char HTTP_BLE_DEV_STYLE[] PROGMEM = "th, td { padding-left:5px; }"; From 4dfa0168552c0de4db321e626737379bad58aec8 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:16:58 +0200 Subject: [PATCH 025/205] Update Italian language (#22340) --- tasmota/language/it_IT.h | 62 ++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 9da62b200..56ceb08af 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.4.0.1 - Last update 27.07.2024 + * Updated until v9.4.0.1 - Last update 22.10.2024 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -573,24 +573,24 @@ #define D_THERMOSTAT_AUTOTUNE_HYBRID "Regolazione automatica (ibrida)" // xdrv_79_esp32_ble.ino -#define D_CONFIGURE_BLE "Configure BLE" -#define D_BLE_PARAMETERS "Bluetooth Settings" -#define D_MQTT_BLE_ENABLE "Enable Bluetooth" -#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" -#define D_BLE_DEVICES "Devices Seen" -#define D_BLE_REMARK "items marked (*) are not stored in config" +#define D_CONFIGURE_BLE "Configura BLE" +#define D_BLE_PARAMETERS "Impostazioni Bluetooth" +#define D_MQTT_BLE_ENABLE "Abilita Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Abilita scansione attiva (*)" +#define D_BLE_DEVICES "Scansione dispositivi" +#define D_BLE_REMARK "gli elementi segnati con (*) non sono memorizzati in config" // xsns_05_ds18b20.ino -#define D_SENSOR_BUSY "Sensore occupato" -#define D_SENSOR_CRC_ERROR "Errore CRC sensore" -#define D_SENSORS_FOUND "Sensori trovati" +#define D_SENSOR_BUSY "Sensore occupato" +#define D_SENSOR_CRC_ERROR "Errore CRC sensore" +#define D_SENSORS_FOUND "Sensori trovati" // xsns_06_dht.ino -#define D_TIMEOUT_WAITING_FOR "Timeout attesa per" -#define D_START_SIGNAL_LOW "inizio segnale basso" -#define D_START_SIGNAL_HIGH "inizio segnale alto" -#define D_PULSE "impulso" -#define D_CHECKSUM_FAILURE "Checksum fallito" +#define D_TIMEOUT_WAITING_FOR "Timeout attesa per" +#define D_START_SIGNAL_LOW "inizio segnale basso" +#define D_START_SIGNAL_HIGH "inizio segnale alto" +#define D_PULSE "impulso" +#define D_CHECKSUM_FAILURE "Checksum fallito" // xsns_07_sht1x.ino #define D_SENSOR_DID_NOT_ACK_COMMAND "Il sensore non ha eseguito il comando ACK" @@ -602,26 +602,26 @@ #define D_PARTICALS_BEYOND "Particelle" // xsns_27_apds9960.ino -#define D_GESTURE "Gesto" -#define D_COLOR_RED "Rosso" -#define D_COLOR_GREEN "Verde" -#define D_COLOR_BLUE "Blu" -#define D_CCT "CCT" -#define D_PROXIMITY "Prossimità" +#define D_GESTURE "Gesto" +#define D_COLOR_RED "Rosso" +#define D_COLOR_GREEN "Verde" +#define D_COLOR_BLUE "Blu" +#define D_CCT "CCT" +#define D_PROXIMITY "Prossimità" // xsns_32_mpu6050.ino -#define D_AX_AXIS "Accelerazione asse X" -#define D_AY_AXIS "Accelerazione asse Y" -#define D_AZ_AXIS "Accelerazione asse Z" -#define D_GX_AXIS "Giroscopio asse X" -#define D_GY_AXIS "Giroscopio asse Y" -#define D_GZ_AXIS "Giroscopio asse Z" +#define D_AX_AXIS "Accelerazione asse X" +#define D_AY_AXIS "Accelerazione asse Y" +#define D_AZ_AXIS "Accelerazione asse Z" +#define D_GX_AXIS "Giroscopio asse X" +#define D_GY_AXIS "Giroscopio asse Y" +#define D_GZ_AXIS "Giroscopio asse Z" // xsns_33_QMC5883L.ino -#define D_MX "Asse X induzione" -#define D_MY "Asse Y induzione" -#define D_MZ "Asse Z induzione" -#define D_MAGNETICFLD "Induzione magnetica" +#define D_MX "Asse X induzione" +#define D_MY "Asse Y induzione" +#define D_MZ "Asse Z induzione" +#define D_MAGNETICFLD "Induzione magnetica" // xsns_34_hx711.ino #define D_HX_CAL_REMOVE "Rimuovi peso" From 2b6acff4f4accb61d66ac5d09a938ef0afcddd2a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:38:56 +0200 Subject: [PATCH 026/205] Bump version to v14.3.0.2 - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups - DALI command `DaliTarget` to set light control broadcast, group number or gear number - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default --- CHANGELOG.md | 23 +- RELEASENOTES.md | 9 +- tasmota/include/tasmota_types.h | 2 +- tasmota/include/tasmota_version.h | 2 +- tasmota/tasmota_support/settings.ino | 3 + tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 504 +++++++++++++++---- 6 files changed, 436 insertions(+), 107 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b19e01d23..e92ca932b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,27 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.3.0.1] +## [14.3.0.2] +### Added +- DALI command `DaliGear` to set max found gear to speed up scan response +- DALI command `DaliGroup` to add gear to groups +- DALI command `DaliTarget` to set light control broadcast, group number or gear number + +### Breaking Changed + +### Changed +- DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` +- DALI set Tasmota light control as default + +### Fixed + +### Removed + +## [14.3.0.1] 20241022 ### Added - BLE track devices with RPA (#22300) - DALI support for short addresses and groups -### Breaking Changed - ### Changed - ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 (#22299) - HASPmota support for page delete and object updates (#22311) @@ -17,9 +31,6 @@ All notable changes to this project will be documented in this file. ### Fixed - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic (#22328) -### Removed - - ## [Released] ## [14.3.0] 20241015 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2403e2b60..21fe02b4e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -114,15 +114,20 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.3.0.1 +## Changelog v14.3.0.2 ### Added -- DALI support for short addresses and groups +- DALI support for short addresses (gear) and groups +- DALI command `DaliGear` to set max found gear to speed up scan response +- DALI command `DaliGroup` to add gear to groups +- DALI command `DaliTarget` to set light control broadcast, group number or gear number - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) ### Breaking Changed ### Changed - ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 [#22299](https://github.com/arendst/Tasmota/issues/22299) +- DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` +- DALI set Tasmota light control as default - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index e7fdbbf0e..241f8c249 100755 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -289,7 +289,7 @@ typedef union { uint32_t influxdb_sensor : 1; // bit 10 (v11.0.0.5) - CMND_IFXSENSOR - Enable sensor support in addition to teleperiod support uint32_t ex_serbridge_console : 1; // bit 11 (v11.1.0.4) - (v14.1.0.2) Replaced by CMND_SSERIALMODE uint32_t telegram_disable_af : 1; // bit 12 (v14.0.0.2) - CMND_TMSTATE 6/7 - Disable Telegram auto-fingerprint fix - uint32_t dali_web : 1; // bit 13 (v14.2.0.6) - CMND_DALIWEB - Enable DALI web controls + uint32_t dali_light : 1; // bit 13 (v14.2.0.6) - CMND_DALILIGHT - Enable Tasmota light controls for DALI uint32_t spare14 : 1; // bit 14 uint32_t spare15 : 1; // bit 15 uint32_t spare16 : 1; // bit 16 diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 152e8fb7d..3813e4d07 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E030001; // 14.3.0.1 +const uint32_t TASMOTA_VERSION = 0x0E030002; // 14.3.0.2 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index 5404dba9d..b74d7c663 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -1835,6 +1835,9 @@ void SettingsDelta(void) { if (Settings->version < 0x0E020004) { // 14.2.0.4 Settings->weight_precision = 0; // Initialized by HX711 driver } + if (Settings->version < 0x0E030002) { // 14.3.0.2 + Settings->sbflag1.dali_light = 1; + } Settings->version = TASMOTA_VERSION; SettingsSave(1); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index 1253fc73e..3dbe46f8e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -19,6 +19,11 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 1.0.0.0 20241022 update - Refactor commission + - Add receive collision detection + 0.1.0.8 20241019 update - Rename command `DaliCommission` to `DaliScan` + - Rename command `DaliWeb` to `DaliLight` + - Add command `DaliGear` to set max found gear to speed up scan response 0.1.0.7 20241017 update - Add command `DaliCommission 1|2` assigning short addresses - Add command `DaliTarget 0, 1..64, 101..116` to select light control address - Add command `DaliGroup1..16 +|-` to add/remove devices from group @@ -50,20 +55,23 @@ * DALI support for Tasmota * * Available commands: - * = 0..255 or 0x00..0xFF + 256/0x100 for optional repeat (send twice) - * = 0..255 or 0x00..0xFF - Both decimal and hexadecimal is supported + * or = 0..255 or 0x00..0xFF + 256/0x100 for optional repeat (send twice) + * or = 0..255 or 0x00..0xFF - Both decimal and hexadecimal is supported * = 0 - DALI default * = 1..64 - DALI short address + 1 * = 101..116 - DALI group + 101 - * DaliSend , - Execute DALI code and do not expect a DALI backward frame - * DaliQuery , - Execute DALI code and report result (DALI backward frame) - * DaliCommission 1|2 - Reset (0) or (1)/and commission device short addresses + * DaliSend , - Execute DALI code and do not expect a DALI backward frame + * DaliSend <0xA3>,,, - Set DALI parameter using DTR0 and do not expect a DALI backward frame + * DaliQuery , - Execute DALI code and report result (DALI backward frame) + * DaliScan 1|2 - Reset (0) or (1)/and commission device short addresses + * DaliGear 1..64 - Set max short address to speed up scanning - default is 64 * DaliGroup<1..16> [+]|-,... - Add(+) or Remove(-) devices to/from group * DaliPower|| 0..254 - Control power (0 = Off, 1 = Last dimmer, 2 = Toggle, 3..254 = absolute light brightness) * DaliDimmer|| 0..100 - Control dimmer (0 = Off, 1..100 = precentage of brightness) - * DaliWeb 0|1 - Enable Tasmota light control for DaliTarget device - * DaliTarget || - Set Tasmota light control device (0, 1..64, 101..116) + * DaliLight 0|1 - Enable Tasmota light control for DaliTarget device + * DaliTarget || - Set Tasmota light control device (0, 1..64, 101..116) - default 0 * + * DALI background information * Address type Address byte * ------------------ -------------------- * Broadcast address 1111111S @@ -73,27 +81,186 @@ * A = Address bit, S = 0 Direct Arc Power control, S = 1 Command, C = Special command \*********************************************************************************************/ -#define XDRV_75 75 +#define XDRV_75 75 #ifndef DALI_IN_INVERT -#define DALI_IN_INVERT 0 // DALI RX inverted +#define DALI_IN_INVERT 0 // DALI RX inverted (1) #endif #ifndef DALI_OUT_INVERT -#define DALI_OUT_INVERT 0 // DALI TX inverted +#define DALI_OUT_INVERT 0 // DALI TX inverted (1) +#endif +#ifndef DALI_MAX_SHORT_ADDRESS +#define DALI_MAX_SHORT_ADDRESS 64 // DALI default max short addresses #endif #ifndef DALI_INIT_STATE -#define DALI_INIT_STATE 50 // DALI init dimmer state 50/254 +#define DALI_INIT_STATE 50 // DALI init dimmer state 50/254 +#endif +#ifndef DALI_INIT_FADE +#define DALI_INIT_FADE 1 // Fade between light states in number of seconds #endif #ifndef DALI_TIMEOUT -#define DALI_TIMEOUT 50 // DALI backward frame receive timeout (ms) +#define DALI_TIMEOUT 50 // DALI backward frame receive timeout (ms) #endif //#define DALI_DEBUG #ifndef DALI_DEBUG_PIN -#define DALI_DEBUG_PIN 4 +#define DALI_DEBUG_PIN 4 // Debug GPIO #endif -#define DALI_BROADCAST_DP 0b11111110 // 0xFE = 254 +// Control commands - Send as second byte without repeat +#define DALI_OFF 0x0000 // 0 - Turns off lighting. +#define DALI_UP 0x0001 // 1 - Increases the lighting control level for 200 ms according to the Fade rate. +#define DALI_DOWN 0x0002 // 2 - Decreases the lighting control level for 200 ms according to the Fade rate. +#define DALI_STEP_UP 0x0003 // 3 - Increments the lighting control level (without fade). +#define DALI_STEP_DOWN 0x0004 // 4 - Decrements the lighting control level (without fade). +#define DALI_RECALL_MAX_LEVEL 0x0005 // 5 - Maximizes the lighting control level (without fade). +#define DALI_RECALL_MIN_LEVEL 0x0006 // 6 - Minimizes the lighting control level (without fade) +#define DALI_STEP_DOWN_AND_OFF 0x0007 // 7 - Decrements the lighting control level and turns off lighting if the level is at the minimum (without fade). +#define DALI_ON_AND_STEP_UP 0x0008 // 8 - Increments the lighting control level and turns on lighting if lighting is off (with fade). +#define DALI_ENABLE_DAPC_SEQUENCE 0x0009 // 9 - It shows the repeat start of the DAPC command. +#define DALI_GO_TO_LAST_ACTIVE_LEVEL 0x000A // 10 - DALI-2 Adjusts the lighting control level to the last light control level according to the Fade time. +#define DALI_RESERVED11 0x000B // 11 - [Reserved] +#define DALI_RESERVED15 0x000F // 15 - [Reserved] +#define DALI_GO_TO_SCENE0 0x0010 // 16 - Adjusts the lighting control level for Scene XXXX according to the fade time. +#define DALI_GO_TO_SCENE15 0x001F // 31 - Adjusts the lighting control level for Scene XXXX according to the fade time. + +// Configuration commands - Send as second byte with repeat +#define DALI_RESET 0x0020 // 32 - Makes a slave an RESET state. +#define DALI_STORE_ACTUAL_LEVEL_IN_THE_DTR0 0x0021 // 33 - Saves the current lighting control level to the DTR (DTR0). +#define DALI_SAVE_PERSISTENT_VARIABLES 0x0022 // 34 - DALI-2 Saves a variable in nonvolatile memory (NVM). +#define DALI_SET_OPERATING_MODE 0x0023 // 35 - DALI-2 Sets data of DTR0 as an operating mode. +#define DALI_RESET_MEMORY_BANK 0x0024 // 36 - DALI-2 Changes to the reset value the specified memory bank in DTR0. +#define DALI_IDENTIFY_DEVICE 0x0025 // 37 - DALI-2 Starts the identification state of the device. +#define DALI_RESERVED38 0x0026 // 38 - [Reserved] +#define DALI_RESERVED41 0x0029 // 41 - [Reserved] +#define DALI_SET_MAX_LEVEL 0x002A // 42 - Specifies the DTR data as the maximum lighting control level. +#define DALI_SET_MIN_LEVEL 0x002B // 43 - Specifies the DTR data as the minimum lighting control level. +#define DALI_SET_SYSTEM_FAILURE_LEVEL 0x002C // 44 - Specifies the DTR data as the "FAILURELEVEL". +#define DALI_SET_POWER_ON_LEVEL 0x002D // 45 - Specifies the DTR data as the "POWER ONLEVEL". +#define DALI_SET_FADE_TIME 0x002E // 46 - Specifies the DTR data as the Fade time. +#define DALI_SET_FADE_RATE 0x002F // 47 - Specifies the DTR data as the Fade rate. +#define DALI_SET_EXTENDED_FADE_TIME 0x0030 // 48 - DALI-2 Specifies the DTR data as the Extended Fade Time. +#define DALI_RESERVED49 0x0031 // 49 - [Reserved] +#define DALI_RESERVED63 0x003F // 63 - [Reserved] +#define DALI_SET_SCENE0 0x0040 // 64 - Specifies the DTR data as Scene XXXX. +#define DALI_SET_SCENE15 0x004F // 79 - Specifies the DTR data as Scene XXXX. +#define DALI_REMOVE_FROM_SCENE0 0x0050 // 80 - Deletes the Scene XXXX setting. (Specifies 1111 1111 for the scene register.) +#define DALI_REMOVE_FROM_SCENE15 0x005F // 95 - Deletes the Scene XXXX setting. (Specifies 1111 1111 for the scene register.) +#define DALI_ADD_TO_GROUP0 0x0060 // 96 - Adds the slave to Group XXXX. +#define DALI_ADD_TO_GROUP15 0x006F // 111 - Adds the slave to Group XXXX. +#define DALI_REMOVE_FROM_GROUP0 0x0070 // 112 - Deletes the slave from Group XXXX. +#define DALI_REMOVE_FROM_GROUP15 0x007F // 127 - Deletes the slave from Group XXXX. +#define DALI_SET_SHORT_ADDRESS 0x0080 // 128 - Specifies the DTR data as a Short Address. +#define DALI_ENABLE_WRITE_MEMORY 0x0081 // 129 - Allows writing of the memory bank. +#define DALI_RESERVED130 0x0082 // 130 - [Reserved] +#define DALI_RESERVED143 0x008F // 143 - [Reserved] + +// Query commands - Send as second byte +#define DALI_QUERY_STATUS 0x0090 // 144 - Returns "STATUS INFORMATION" +#define DALI_QUERY_CONTROL_GEAR_PRESENT 0x0091 // 145 - Is there a slave that can communicate? +#define DALI_QUERY_LAMP_FAILURE 0x0092 // 146 - Is there a lamp problem? +#define DALI_QUERY_LAMP_POWER_ON 0x0093 // 147 - Is a lamp on? +#define DALI_QUERY_LIMIT_ERROR 0x0094 // 148 - Is the specified lighting control level out of the range from the minimum to the maximum values? +#define DALI_QUERY_RESET_STATE 0x0095 // 149 - Is the slave in 'RESET STATE'? +#define DALI_QUERY_MISSING_SHORT_ADDRESS 0x0096 // 150 - Does the slave not have a short address? +#define DALI_QUERY_VERSION_NUMBER 0x0097 // 151 - What is the corresponding IEC standard number? +#define DALI_QUERY_CONTENT_DTR0 0x0098 // 152 - What is the DTR content? +#define DALI_QUERY_DEVICE_TYPE 0x0099 // 153 - What is the device type? (fluorescent lamp:0000 0000) (IEC62386-207 is 6 fixed) +#define DALI_QUERY_PHYSICAL_MINIMUM_LEVEL 0x009A // 154 - What is the minimum lighting control level specified by the hardware? +#define DALI_QUERY_POWER_FAILURE 0x009B // 155 - Has the slave operated without the execution of reset-command or the adjustment of the lighting control level? +#define DALI_QUERY_CONTENT_DTR1 0x009C // 156 - What is the DTR1 content? +#define DALI_QUERY_CONTENT_DTR2 0x009D // 157 - What is the DTR2 content? +#define DALI_QUERY_OPERATING_MODE 0x009E // 158 - DALI-2 What is the Operating Mode? +#define DALI_QUERY_LIGHT_SOURCE_TYPE 0x009F // 159 - DALI-2 What is the Light source type? +#define DALI_QUERY_ACTUAL_LEVEL 0x00A0 // 160 - What is the "ACTUAL LEVEL" (the current lighting control level)? +#define DALI_QUERY_MAX_LEVEL 0x00A1 // 161 - What is the maximum lighting control level? +#define DALI_QUERY_MIN_LEVEL 0x00A2 // 162 - What is the minimum lighting control level? +#define DALI_QUERY_POWER_ON_LEVEL 0x00A3 // 163 - What is the "POWER ON LEVEL" (the lighting control level when the power is turned on)? +#define DALI_QUERY_SYSTEM_FAILURE_LEVEL 0x00A4 // 164 - What is the "SYSTEM FAILURE LEVEL" (the lighting control level when a failure occurs)? +#define DALI_QUERY_FADE_TIME_FADE_RATE 0x00A5 // 165 - What are the Fade time and Fade rate? +#define DALI_QUERY_MANUFACTURER_SPECIFIC_MODE 0x00A6 // 166 - DALI-2 What is the Specific Mode? +#define DALI_QUERY_NEXT_DEVICE_TYPE 0x00A7 // 167 - DALI-2 What is the next Device Type? +#define DALI_QUERY_EXTENDED_FADE_TIME 0x00A8 // 168 - DALI-2 What is the Extended Fade Time? +#define DALI_QUERY_CONTROL_GEAR_FAILURE 0x00A9 // 169 - DALI-2 Does a slave have the abnormality? +#define DALI_RESERVED170 0x00AA // 170 - [Reserved] +#define DALI_RESERVED175 0x00AF // 175 - [Reserved] +#define DALI_QUERY_SCENE0_LEVEL 0x00B0 // 176 - What is the lighting control level for SCENE XXXX? +#define DALI_QUERY_GROUPS_0_7 0x00C0 // 192 - Does the slave belong to a group among groups 0 to 7? (Each bit corresponds to a group.) +#define DALI_QUERY_GROUPS_8_15 0x00C1 // 193 - Does the slave belong to a group among groups 8 to 15? (Each bit corresponds to a group.) +#define DALI_QUERY_RANDOM_ADDRESS_H 0x00C2 // 194 - What are the higher 8 bits of the random address? +#define DALI_QUERY_RANDOM_ADDRESS_M 0x00C3 // 195 - What are the middle 8 bits of the random address? +#define DALI_QUERY_RANDOM_ADDRESS_L 0x00C4 // 196 - What are the lower 8 bits of the random address? +#define DALI_READ_MEMORY_LOCATION 0x00C5 // 197 - What is the memory location content? +#define DALI_RESERVED198 0x00C6 // 198 - [Reserved] +#define DALI_RESERVED223 0x00DF // 223 - [Reserved] + +// Application extended configuration commands - Send as second byte +#define DALI_REFERENCE_SYSTEM_POWER 0x00E0 // 224 - IEC62386-207 Starts power measurement. +#define DALI_ENABLE_CURRENT_PROTECTOR 0x00E1 // 225 - IEC62386-207 Enables the current protection. +#define DALI_DISABLE_CURRENT_PROTECTOR 0x00E2 // 226 - IEC62386-207 Disables the current protection. +#define DALI_SELECT_DIMMING_CURVE 0x00E3 // 227 - IEC62386-207 Selects Dimming curve. +#define DALI_STORE_DTR_AS_FAST_FADE_TIME 0x00E4 // 228 - IEC62386-207 Sets the DTR of the data as Fast Fade Time. +#define DALI_RESERVED229 0x00E5 // 229 - [Reserved] +#define DALI_RESERVED236 0x00EC // 236 - [Reserved] + +// Application extended query commands - Send as second byte +#define DALI_QUERY_GEAR_TYPE 0x00ED // 237 - IEC62386-207 Returns ‘GEAR TYPE’ +#define DALI_QUERY_DIMMING_CURVE 0x00EE // 238 - IEC62386-207 Returns ’Dimming curve’in use +#define DALI_QUERY_POSSIBLE_OPERATING_MODE 0x00EF // 239 - IEC62386-207 Returns ‘POSSIBLE OPERATING MODE’ +#define DALI_QUERY_FEATURES 0x00F0 // 240 - IEC62386-207 Returns ‘FEATURES’ +#define DALI_QUERY_FAILURE_STATUS 0x00F1 // 241 - IEC62386-207 Returns ‘FAILURE STATUS’ +#define DALI_QUERY_SHORT_CIRCUIT 0x00F2 // 242 - IEC62386-207 Returns bit0 short circuit of ‘FAILURE STATUS’ +#define DALI_QUERY_OPEN_CIRCUIT 0x00F3 // 243 - IEC62386-207 Returns bit1 open circuit of ‘FAILURE STATUS’ +#define DALI_QUERY_LOAD_DECREASE 0x00F4 // 244 - IEC62386-207 Returns bit2 load decrease of ‘FAILURE STATUS’ +#define DALI_QUERY_LOAD_INDREASE 0x00F5 // 245 - IEC62386-207 Returns bit3 load increase of‘FAILURE STATUS’ +#define DALI_QUERY_CURRENT_PROTECTOR_ACTIVE 0x00F6 // 246 - IEC62386-207 Returns bit4 current protector active of ‘FAILURE STATUS’ +#define DALI_QUERY_THERMAL_SHUTDOWN 0x00F7 // 247 - IEC62386-207 Returns bit5 thermal shut down of ‘FAILURE STATUS’ +#define DALI_QUERY_THERMAL_OVERLOAD 0x00F8 // 248 - IEC62386-207 Returns bit6 thermal overload with light level reduction of ‘FAILURE STATUS’ +#define DALI_QUERY_REFARENCE_RUNNING 0x00F9 // 249 - IEC62386-207 Returns whetherReference System Power is in operation. +#define DALI_QUERY_REFERENCE_MEASURMENT_FAILED 0x00FA // 250 - IEC62386-207 Returns bit7 reference measurement failed of ‘FAILURE STATUS’ +#define DALI_QUERY_CURRENT_PROTECTOR_ENABLE 0x00FB // 251 - IEC62386-207 Returns state of Curent protector +#define DALI_QUERY_OPERATING_MODE2 0x00FC // 252 - IEC62386-207 Returns ‘OPERATING MODE’ +#define DALI_QUERY_FAST_FADE_TIME 0x00FD // 253 - IEC62386-207 Returns set Fast fade time. +#define DALI_QUERY_MIN_FAST_FADE_TIME 0x00FE // 254 - IEC62386-207 Returns set Minimum fast fade time +#define DALI_QUERY_EXTENDED_VERSION_NUMBER 0x00FF // 255 - IEC62386-207 The version number of the extended support? IEC62386-207: 1, Other: NO(no response) + +// Address types - Send as first byte +#define DALI_SHORT_ADDRESS0 0x0000 // 0b00000000 0 - First short address +#define DALI_SHORT_ADDRESS1 0x0002 // 0b00000010 1 - Next short address +#define DALI_SHORT_ADDRESS63 0x007E // 0b01111110 63 - Last short address +#define DALI_GROUP_ADDRESS0 0x0080 // 0b10000000 0 - First group address +#define DALI_GROUP_ADDRESS1 0x0082 // 0b10000010 1 - Next group address +#define DALI_GROUP_ADDRESS15 0x009E // 0b10011110 15 - Last group address + +// Special commands - Send as first byte +#define DALI_TERMINATE 0x00A1 // 256 - Releases the INITIALISE state. +#define DALI_DATA_TRANSFER_REGISTER0 0x00A3 // 257 - Stores the data XXXX XXXX to the DTR(DTR0). +#define DALI_INITIALISE 0x01A5 // 258 REPEAT - Sets the slave to the INITIALISE status for15 minutes. Commands 259 to 270 are enabled only for a slave in this status. +#define DALI_RANDOMISE 0x01A7 // 259 REPEAT - Generates a random address. +#define DALI_COMPARE 0x00A9 // 260 - Is the random address smaller or equal to the search address? +#define DALI_WITHDRAW 0x00AB // 261 - Excludes slaves for which the random address and search address match from the Compare process. +#define DALI_RESERVED262 0x00AD // 262 - [Reserved] +#define DALI_PING 0x00AF // 263 - DALI-2 Ignores in the slave. +#define DALI_SEARCHADDRH 0x00B1 // 264 - Specifies the higher 8 bits of the search address. +#define DALI_SEARCHADDRM 0x00B3 // 265 - Specifies the middle 8 bits of the search address. +#define DALI_SEARCHADDRL 0x00B5 // 266 - Specifies the lower 8 bits of the search address. +#define DALI_PROGRAM_SHORT_ADDRESS 0x00B7 // 267 - The slave shall store the received 6-bit address (AAA AAA) as a short address if it is selected. +#define DALI_VERIFY_SHORT_ADDRESS 0x00B9 // 268 - Is the short address AAA AAA? +#define DALI_QUERY_SHORT_ADDRESS 0x00BB // 269 - What is the short address of the slaveNote 2being selected? +#define DALI_PHYSICAL_SELECTION 0x00BD // 270 - not DALI-2 Sets the slave to Physical Selection Mode and excludes the slave from the Compare process. (Excluding IEC62386-102ed2.0) +#define DALI_RESERVED271 0x00BF // 271 - [Reserved] + +// Extending special commands - Send as first byte +#define DALI_ENABLE_DEVICE_TYPE_X 0x00C1 // 272 - Adds the device XXXX (a special device). +#define DALI_DATA_TRANSFER_REGISTER1 0x00C3 // 273 - Stores data XXXX into DTR1. +#define DALI_DATA_TRANSFER_REGISTER2 0x00C5 // 274 - Stores data XXXX into DTR2. +#define DALI_WRITE_MEMORY_LOCATION 0x00C7 // 275 - Write data into the specified address of the specified memory bank. (There is BW) (DTR(DTR0):address, DTR1:memory bank number) +#define DALI_WRITE_MEMORY_LOCATION_NO_REPLY 0x00C9 // 276 - DALI-2 Write data into the specified address of the specified memory bank. (There is no BW) (DTR(DTR0):address, TR1:memory bank number) +#define DALI_RESERVED277 0x00CB // 277 - [Reserved] +#define DALI_RESERVED349 0x00FD // 349 - [Reserved] + +// Address type - Send as first byte +#define DALI_BROADCAST_DP 0x00FE // 0b11111110 254 - Broadcast address #define DALI_TOPIC "DALI" #define D_PRFX_DALI "Dali" @@ -101,22 +268,24 @@ const char kDALICommands[] PROGMEM = D_PRFX_DALI "|" // Prefix "|" D_CMND_POWER "|" D_CMND_DIMMER "|Target" #ifdef USE_LIGHT - "|Web" + "|Light" #endif // USE_LIGHT - "|Send|Query|Commission|Group"; + "|Send|Query|Scan|Group|Gear"; void (* const DALICommand[])(void) PROGMEM = { &CmndDali, &CmndDaliPower, &CmndDaliDimmer, &CmndDaliTarget, #ifdef USE_LIGHT - &CmndDaliWeb, + &CmndDaliLight, #endif // USE_LIGHT - &CmndDaliSend, &CmndDaliQuery, &CmndDaliCommission, &CmndDaliGroup }; + &CmndDaliSend, &CmndDaliQuery, &CmndDaliScan, &CmndDaliGroup, &CmndDaliGear }; struct DALI { uint32_t bit_time; - uint16_t received_dali_data; // Data received from DALI bus + uint32_t last_activity; + uint32_t received_dali_data; // Data received from DALI bus uint8_t pin_rx; uint8_t pin_tx; + uint8_t max_short_address; uint8_t address; uint8_t command; uint8_t dimmer; @@ -125,6 +294,7 @@ struct DALI { bool available; bool response; bool light_sync; + bool probe; } *Dali = nullptr; /*********************************************************************************************\ @@ -149,6 +319,7 @@ uint32_t DaliTarget2Address(uint32_t target) { } return target &0xFE; // Direct Arc Power Control command } + /* uint32_t DaliAddress2Target(uint32_t adr) { if (adr >= 254) { // 0b1111111S @@ -160,6 +331,7 @@ uint32_t DaliAddress2Target(uint32_t adr) { return (adr >> 1) +1; // 0b0000000S .. 0b0111111S Short address (1 .. 64) } */ + void DaliEnableRxInterrupt(void) { Dali->available = false; attachInterrupt(Dali->pin_rx, DaliReceiveData, FALLING); @@ -169,7 +341,9 @@ void DaliDisableRxInterrupt(void) { detachInterrupt(Dali->pin_rx); } -/*************** R E C E I V E * P R O C E D U R E *********/ +/*-------------------------------------------------------------------------------------------*\ + * DALI receive +\*-------------------------------------------------------------------------------------------*/ void IRAM_ATTR DaliReceiveData(void); // Fix ESP8266 ISR not in IRAM! exception void DaliReceiveData(void) { @@ -190,6 +364,7 @@ void DaliReceiveData(void) { 1 2 3 */ if (Dali->available) { return; } // Skip if last input is not yet handled + uint32_t gap_time = millis() - Dali->last_activity; uint32_t wait = ESP.getCycleCount() + (Dali->bit_time / 2); int bit_state = 0; bool dali_read; @@ -216,7 +391,7 @@ void DaliReceiveData(void) { bit_state = 0; bit_number = 35; } - else if (abs(bit_state) > 1) { // Invalid manchester data + else if (abs(bit_state) > 1) { // Invalid manchester data (too many 0 or 1) break; } } else { // 4 high Stop bits @@ -230,16 +405,28 @@ void DaliReceiveData(void) { } bit_number++; } - if (0 == bit_state) { // Valid Manchester encoding including start and stop bits + Dali->last_activity = millis(); + + if (bit_state != 0) { // Invalid Manchester encoding including start and stop bits + received_dali_data |= 0x00010000; // Possible collision or invalid reply of repeated frame due to handling of first frame + if (Dali->response) { // Expect backward frame with no collision + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DLI: Rx collision")); + } + } + if (Dali->probe) { + AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Rx %05X %d"), received_dali_data, gap_time); + } else { if (Dali->response || // Response from last message send (Dali->received_dali_data != received_dali_data)) { // Skip duplicates Dali->received_dali_data = received_dali_data; - Dali->available = true; // Valid data received + Dali->available = true; // Any data received } } } -/*************** S E N D * P R O C E D U R E ***************/ +/*-------------------------------------------------------------------------------------------*\ + * DALI send +\*-------------------------------------------------------------------------------------------*/ void DaliSendDataOnce(uint16_t send_dali_data) { /* @@ -252,6 +439,10 @@ void DaliSendDataOnce(uint16_t send_dali_data) { Bit number 01234567890123456789012345678901234567 1 2 3 */ + Dali->last_activity += 14; // As suggested by DALI protocol (> 9.17 ms) + while (!TimeReached(Dali->last_activity)) { + delay(1); // Wait for bus to be free if needed + } bool bit_value; bool pin_value; bool dali_read; @@ -285,15 +476,18 @@ void DaliSendDataOnce(uint16_t send_dali_data) { collision = true; pin_value = LOW; bit_number = 29; // Keep bus low for 4 bits - AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Send collision")); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DLI: Tx collision")); } } bit_number++; } // delayMicroseconds(1100); // Adds to total 15.8 ms + Dali->last_activity = millis(); } +/*-------------------------------------------------------------------------------------------*/ + void DaliSendData(uint32_t adr, uint32_t cmd) { bool repeat = (adr &0x100); // Set repeat if bit 8 is set adr &= 0xFF; @@ -328,16 +522,16 @@ void DaliSendData(uint32_t adr, uint32_t cmd) { uint16_t send_dali_data = adr << 8 | cmd; DaliDisableRxInterrupt(); - delay(3); // Settling time between forward and backward frame DaliSendDataOnce(send_dali_data); // Takes 14.7 ms if (repeat) { - delay(14); // As used by Busch-Jaeger and suggested by DALI protocol (> 9.17 ms) DaliSendDataOnce(send_dali_data); // Takes 14.7 ms } delay(2); // Block response DaliEnableRxInterrupt(); } +/*-------------------------------------------------------------------------------------------*/ + int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout = DALI_TIMEOUT); int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout) { Dali->response = true; @@ -347,8 +541,8 @@ int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout) { }; int result = -1; // DALI NO or no response if (Dali->available) { - Dali->available = false; - result = Dali->received_dali_data; + Dali->available = false; // DALI collision (-2) or valid data (>=0) + result = (Dali->received_dali_data &0x00010000) ? -2 : Dali->received_dali_data; } Dali->response = false; @@ -360,24 +554,70 @@ int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout) { } /*********************************************************************************************\ - * DALI commissioning short addresses + * DALI tools * * Courtesy of https://github.com/qqqlab/DALI-Lighting-Interface \*********************************************************************************************/ -// Query commands - Send as second byte -#define DALI_QUERY_STATUS 0x0090 // 144 - Returns "STATUS INFORMATION" +bool DaliSetValue(uint32_t adr, uint32_t getcmd, uint32_t setcmd, uint32_t v) { + // Set a parameter value, returns true on success + int current_v = DaliSendWaitResponse(adr, getcmd); // Get current parameter value + if (current_v == v) { return true; } // Already set + DaliSendData(DALI_DATA_TRANSFER_REGISTER0, v); // Store value in DTR + int dtr = DaliSendWaitResponse(adr, DALI_QUERY_CONTENT_DTR0); // Get DTR value + if (dtr != v) { return false; } + DaliSendData(adr, setcmd); // Set parameter value = DTR + current_v = DaliSendWaitResponse(adr, getcmd); // Get current parameter value + if (current_v != v) { return false; } // Set failed + return true; +} -// Special commands - Send as first byte -#define DALI_TERMINATE 0x00A1 // 256 - Releases the INITIALISE state. -#define DALI_INITIALISE 0x01A5 // 258 REPEAT - Sets the slave to the INITIALISE status for15 minutes. Commands 259 to 270 are enabled only for a slave in this status. -#define DALI_RANDOMISE 0x01A7 // 259 REPEAT - Generates a random address. -#define DALI_COMPARE 0x00A9 // 260 - Is the random address smaller or equal to the search address? -#define DALI_WITHDRAW 0x00AB // 261 - Excludes slaves for which the random address and search address match from the Compare process. -#define DALI_SEARCHADDRH 0x00B1 // 264 - Specifies the higher 8 bits of the search address. -#define DALI_SEARCHADDRM 0x00B3 // 265 - Specifies the middle 8 bits of the search address. -#define DALI_SEARCHADDRL 0x00B5 // 266 - Specifies the lower 8 bits of the search address. -#define DALI_PROGRAM_SHORT_ADDRESS 0x00B7 // 267 - The slave shall store the received 6-bit address (AAA AAA) as a short address if it is selected. +bool DaliSetOperatingMode(uint32_t adr, uint32_t v) { + return DaliSetValue(adr, DALI_QUERY_OPERATING_MODE, DALI_SET_OPERATING_MODE, v); +} + +bool DaliSetMaxLevel(uint32_t adr, uint32_t v) { + return DaliSetValue(adr, DALI_QUERY_MAX_LEVEL, DALI_SET_MAX_LEVEL, v); +} + +bool DaliSetMinLevel(uint32_t adr, uint32_t v) { + return DaliSetValue(adr, DALI_QUERY_MIN_LEVEL, DALI_SET_MIN_LEVEL, v); +} + +bool DaliSetSystemFailureLevel(uint32_t adr, uint32_t v) { + return DaliSetValue(adr, DALI_QUERY_SYSTEM_FAILURE_LEVEL, DALI_SET_SYSTEM_FAILURE_LEVEL, v); +} + +bool DaliSetPowerOnLevel(uint32_t adr, uint32_t v) { + return DaliSetValue(adr, DALI_QUERY_POWER_ON_LEVEL, DALI_SET_POWER_ON_LEVEL, v); +} + +uint32_t DaliGearPresent(void) { + uint32_t count = 0; + for (uint32_t sa = 0; sa < Dali->max_short_address; sa++) { // Scanning 64 addresses takes about 2500 ms + if (DaliSendWaitResponse(sa << 1 | 1, DALI_QUERY_CONTROL_GEAR_PRESENT, 20) >= 0) { + count++; + } + } + return count; +} + +void DaliInitLight(void) { + // Taken from Shelly Dali Dimmer ;-) + Settings->light_fade = 0; // Use Dali fading + DaliSendData(DALI_DATA_TRANSFER_REGISTER0, DALI_INIT_FADE); // Fade x second + DaliSendData(0xFF, DALI_SET_FADE_TIME); + DaliSendData(DALI_DATA_TRANSFER_REGISTER0, 0); // Power off after gear power restore + DaliSendData(0xFF, DALI_SET_POWER_ON_LEVEL); + DaliSendData(DALI_DATA_TRANSFER_REGISTER0, 0xFE); // Reset all but short circuit + DaliSendData(0xFF, DALI_SET_SYSTEM_FAILURE_LEVEL); +} + +/*********************************************************************************************\ + * DALI commissioning short addresses + * + * Courtesy of https://github.com/qqqlab/DALI-Lighting-Interface +\*********************************************************************************************/ void DaliSetSearchAddress(uint32_t adr) { // Set search address @@ -386,6 +626,8 @@ void DaliSetSearchAddress(uint32_t adr) { DaliSendData(DALI_SEARCHADDRL, adr); } +/*-------------------------------------------------------------------------------------------*/ + void DaliSetSearchAddressDifference(uint32_t adr_new, uint32_t adr_current) { // Set search address, but set only changed bytes (takes less time) if ( (uint8_t)(adr_new>>16) != (uint8_t)(adr_current>>16) ) DaliSendData(DALI_SEARCHADDRH, adr_new>>16); @@ -393,6 +635,8 @@ void DaliSetSearchAddressDifference(uint32_t adr_new, uint32_t adr_current) { if ( (uint8_t)(adr_new) != (uint8_t)(adr_current) ) DaliSendData(DALI_SEARCHADDRL, adr_new); } +/*-------------------------------------------------------------------------------------------*/ + bool DaliCompare() { // Is the random address smaller or equal to the search address? // As more than one device can reply, the reply gets garbled @@ -402,11 +646,14 @@ bool DaliCompare() { // Sometimes the reply is not registered... so only accept retry times 'no reply' as a real false compare int rv = DaliSendWaitResponse(DALI_COMPARE, 0x00); if (rv == 0xFF) return true; // Yes reply + if (rv == -2) return true; // Reply but collision retry--; } return false; } +/*-------------------------------------------------------------------------------------------*/ + uint32_t DaliFindAddress(void) { // Find addr with binary search uint32_t adr = 0x800000; @@ -433,6 +680,8 @@ uint32_t DaliFindAddress(void) { return adr; } +/*-------------------------------------------------------------------------------------------*/ + void DaliProgramShortAddress(uint8_t shortadr) { // The slave shall store the received 6-bit address (AAAAAA) as a short address if it is selected. DaliSendData(DALI_PROGRAM_SHORT_ADDRESS, (shortadr << 1) | 0x01); @@ -440,34 +689,29 @@ void DaliProgramShortAddress(uint8_t shortadr) { AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Set short address %d"), shortadr +1); } +/*-------------------------------------------------------------------------------------------*/ + uint32_t DaliCommission(uint8_t init_arg) { + // Based on Shelly DALI Dimmer Gen3 received frames // init_arg=11111111 : all without short address // init_arg=00000000 : all // init_arg=0AAAAAA1 : only for this shortadr // returns number of new short addresses assigned - DaliSendData(DALI_BROADCAST_DP, 0); // Turn all OFF - delay(100); // Need 100ms pause before starting commissioning - + DaliSendData(0xFF, DALI_RESET); // Turns ON all lights uint8_t arr[64]; uint32_t sa; for (sa = 0; sa < 64; sa++) { arr[sa] = 0; } - + delay(450); + DaliSendData(DALI_DATA_TRANSFER_REGISTER0, 0xFF); + DaliSendData(0xFF, DALI_SET_SHORT_ADDRESS); + DaliSendData(DALI_TERMINATE, 0x00); // Terminate the DALI_INITIALISE command + delay(15); // Start commissioning DaliSendData(DALI_INITIALISE, init_arg); DaliSendData(DALI_RANDOMISE, 0x00); - delay(100); // Need 100ms pause after RANDOMISE - - // Find used short addresses (run always, seems to work better than without...) - for (sa = 0; sa < 64; sa++) { - int rv = DaliSendWaitResponse(sa << 1 | 1, DALI_QUERY_STATUS); - if (rv >= 0) { - if (init_arg != 0b00000000) { - arr[sa] = 1; // Remove address from list if not in "all" mode - } - } - } + delay(65); // Need pause after RANDOMISE uint32_t cnt = 0; while (true) { // Find random addresses and assign unused short addresses @@ -476,40 +720,32 @@ uint32_t DaliCommission(uint8_t init_arg) { for (sa = 0; sa < 64; sa++) { // Find first unused short address if (0 == arr[sa]) { break; } } - if( sa >= 64) { break; } // All 64 short addresses assigned -> exit + if (sa >= 64) { break; } // All 64 short addresses assigned -> exit arr[sa] = 1; // Mark short address as used cnt++; DaliProgramShortAddress(sa); // Assign short address DaliSendData(DALI_WITHDRAW, 0x00); // Remove the device from the search + DaliSendData(sa << 1, DALI_OFF); // Turns OFF latest short address light delay(1); - OsWatchLoop(); + OsWatchLoop(); // Feed blocked-loop watchdog } + delay(100); DaliSendData(DALI_TERMINATE, 0x00); // Terminate the DALI_INITIALISE command - for (sa = 0; sa < cnt; sa++) { - AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Flash short address %d"), sa +1); - - DaliSendData(sa << 1, 200); // Flash assigned lights - delay(1000); - OsWatchLoop(); - DaliSendData(sa << 1, 0); - } - +#ifdef USE_LIGHT + DaliInitLight(); + uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address(Dali->target) : DALI_BROADCAST_DP; + DaliSendData(address, Dali->dimmer); // Restore lights +#else + DaliSendData(DALI_BROADCAST_DP, Dali->dimmer); // Restore lights +#endif // USE_LIGHT return cnt; } -/*********************************************************************************************\ - * DALI group management -\*********************************************************************************************/ - -// Configuration commands - Send as second byte -#define DALI_ADD_TO_GROUP0 0x0060 // 96 - Adds the slave to Group XXXX. -#define DALI_REMOVE_FROM_GROUP0 0x0070 // 112 - Deletes the slave from Group XXXX. - -/***********************************************************/ +/*********************************************************************************************/ void ResponseAppendDali(void) { uint8_t dimmer = changeUIntScale(Dali->dimmer, 0, 254, 0, 100); @@ -523,8 +759,14 @@ void ResponseDali(void) { ResponseJsonEnd(); } -void DaliInput(void) { +/*-------------------------------------------------------------------------------------------*/ + +void DaliLoop(void) { if (!Dali->available || Dali->response) { return; } + if (Dali->received_dali_data &0x00010000) { + Dali->available = false; + return; // Rx collision + } Dali->address = Dali->received_dali_data >> 8; Dali->command = Dali->received_dali_data; @@ -538,7 +780,7 @@ void DaliInput(void) { if (Dali->power) { Dali->dimmer = Dali->command; // Value } - if (Settings->sbflag1.dali_web) { // DaliWeb 1 + if (Settings->sbflag1.dali_light) { // DaliLight 1 uint8_t dimmer_new = changeUIntScale(Dali->dimmer, 0, 254, 0, 100); if (power_old != Dali->power) { Dali->light_sync = true; // Block local loop @@ -571,9 +813,20 @@ void DaliInput(void) { Dali->available = false; } +/*-------------------------------------------------------------------------------------------*/ + #ifdef USE_LIGHT +void DaliEverySecond(void) { + if (Settings->sbflag1.dali_light) { // DaliLight 1 + if (5 == TasmotaGlobal.uptime) { + DaliInitLight(); + } + } +} + bool DaliSetChannels(void) { - if (Settings->sbflag1.dali_web) { // DaliWeb 1 + if (Settings->sbflag1.dali_light) { // DaliLight 1 + Settings->light_fade = 0; // Use Dali fading if (Dali->light_sync) { // Block local loop Dali->light_sync = false; } else { @@ -586,6 +839,8 @@ bool DaliSetChannels(void) { } #endif // USE_LIGHT +/*-------------------------------------------------------------------------------------------*/ + bool DaliInit(void) { if (!PinUsed(GPIO_DALI_TX) || !PinUsed(GPIO_DALI_RX)) { return false; } @@ -605,6 +860,7 @@ bool DaliInit(void) { digitalWrite(DALI_DEBUG_PIN, HIGH); #endif // DALI_DEBUG + Dali->max_short_address = (DALI_MAX_SHORT_ADDRESS <= 64) ? DALI_MAX_SHORT_ADDRESS : 64; Dali->dimmer = DALI_INIT_STATE; // Manchester twice 1200 bps = 2400 bps = 417 (protocol 416.76 +/- 10%) us Dali->bit_time = ESP.getCpuFreqMHz() * 1000000 / 2400; @@ -612,10 +868,11 @@ bool DaliInit(void) { DaliEnableRxInterrupt(); #ifdef USE_LIGHT - if (!Settings->sbflag1.dali_web) { // DaliWeb 0 + if (!Settings->sbflag1.dali_light) { // DaliLight 0 return false; } + Settings->light_fade = 0; // Use Dali fading instead UpdateDevicesPresent(1); TasmotaGlobal.light_type = LT_SERIAL1; // Single channel return true; @@ -677,12 +934,20 @@ bool DaliJsonParse(void) { void CmndDali(void) { // Dali {"addr":254,"cmd":100} - Any address and/or command + // Dali 0|1 - Enable DALI receive probe if (XdrvMailbox.data_len > 0) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Dali->probe = XdrvMailbox.payload; + ResponseCmndNumber(Dali->probe); + return; + } DaliJsonParse(); } ResponseDali(); } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliTarget(void) { // DaliTarget - Set transmit target // DaliTarget 0 - Set target to broadcast address @@ -755,8 +1020,12 @@ void CmndDaliGroup(void) { // DaliGroup1 1,2 - Add device 1 and 2 to group 1 // DaliGroup1 -1,2 - Remove device 1 and 2 to group 1 if ((XdrvMailbox.index >= 1) && (XdrvMailbox.index <= 16)) { + uint32_t group = XdrvMailbox.index -1; + bool more = false; + char temp[200] = { 0 }; if (XdrvMailbox.data_len) { uint32_t command = DALI_ADD_TO_GROUP0; + temp[0] = '+'; if ('+' == XdrvMailbox.data[0]) { // Add devices XdrvMailbox.data++; XdrvMailbox.data_len--; @@ -765,34 +1034,72 @@ void CmndDaliGroup(void) { command = DALI_REMOVE_FROM_GROUP0; XdrvMailbox.data++; XdrvMailbox.data_len--; + temp[0] = '-'; } uint32_t argc = ArgC(); // Number of devices if (argc) { - command |= (XdrvMailbox.index -1); + command |= group; uint32_t sas[argc]; ParseParameters(argc, sas); for (uint32_t arg = 0; arg < argc; arg++) { uint32_t sa = sas[arg] -1; - if (sa <= 63) { - DaliSendData(sa << 1 | 0x01, command); + if (sa < 64) { + snprintf_P(temp, sizeof(temp), PSTR("%s%s%d"), temp, (more)?",":"", sa +1); + more = true; + DaliSendData(sa << 1 | 1, command); } } - ResponseCmndDone(); + ResponseCmndIdxChar(temp); } + } else { + uint32_t command = DALI_QUERY_GROUPS_0_7; + uint32_t bitmask = 1 << group; + if (group > 7) { + command = DALI_QUERY_GROUPS_8_15; + bitmask = 1 << group - 8; + } + for (uint32_t sa = 0; sa < Dali->max_short_address; sa++) { // Scanning 64 addresses takes about 2500 ms + int result = DaliSendWaitResponse(sa << 1 | 1, command, 20); + if ((result >= 0) && (result & bitmask)) { + snprintf_P(temp, sizeof(temp), PSTR("%s%s%d"), temp, (more)?",":"", sa +1); + more = true; + } + } + if (!strlen(temp)) { + snprintf_P(temp, sizeof(temp), PSTR("None")); + } + ResponseCmndIdxChar(temp); } } } +void CmndDaliGear(void) { + if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 64)) { + Dali->max_short_address = XdrvMailbox.payload; + } + uint32_t count = DaliGearPresent(); + ResponseCmnd(); + ResponseAppend_P(PSTR("%d,\"Present\":%d}"), Dali->max_short_address, count); +} + void CmndDaliSend(void) { // Send command // Setting bit 8 will repeat command once // DaliSend 0x1a5,255 - DALI Initialise (send twice) - uint32_t values[2] = { 0 }; - uint32_t params = ParseParameters(2, values); + // DaliSend 0x01,0xa3,0x2d,254 - Set Power On level + uint32_t values[4] = { 0 }; + uint32_t params = ParseParameters(4, values); if (2 == params) { DaliSendData(values[0] &0x1FF, values[1] &0xFF); ResponseCmndDone(); } + else if (4 == params) { + if (DaliSetValue(values[0] &0x1FF, values[1] &0xFF, values[2] &0xFF, values[3] &0xFF)) { + ResponseCmndDone(); + } else { + ResponseCmndFailed(); + } + } } void CmndDaliQuery(void) { @@ -808,10 +1115,10 @@ void CmndDaliQuery(void) { } } -void CmndDaliCommission(void) { - // Commission short addresses - // DaliCommission 1 - Reset and commission short addresses - // DaliCommission 2 - Commission unassigned short addresses +void CmndDaliScan(void) { + // Scan short addresses + // DaliScan 1 - Reset and commission short addresses + // DaliScan 2 - Commission unassigned short addresses if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 2)) { uint32_t init_arg = 0x00; // Commission all if (2 == XdrvMailbox.payload) { @@ -823,14 +1130,14 @@ void CmndDaliCommission(void) { } #ifdef USE_LIGHT -void CmndDaliWeb(void) { - // DaliWeb 0 - Disable GUI light controls - // DaliWeb 1 - Enable GUI light controls +void CmndDaliLight(void) { + // DaliLight 0 - Disable light controls + // DaliLight 1 - Enable light controls if (XdrvMailbox.data_len > 0) { - Settings->sbflag1.dali_web = XdrvMailbox.payload &1; + Settings->sbflag1.dali_light = XdrvMailbox.payload &1; TasmotaGlobal.restart_flag = 2; } - ResponseCmndStateText(Settings->sbflag1.dali_web); + ResponseCmndStateText(Settings->sbflag1.dali_light); } #endif // USE_LIGHT @@ -858,9 +1165,12 @@ bool Xdrv75(uint32_t function) { else if (Dali) { switch (function) { case FUNC_LOOP: - DaliInput(); + DaliLoop(); break; #ifdef USE_LIGHT + case FUNC_EVERY_SECOND: + DaliEverySecond(); + break; case FUNC_SET_CHANNELS: result = DaliSetChannels(); break; From 6b094ede16a66223cd26d94ef999d8b08d440746 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Tue, 22 Oct 2024 13:59:04 +0200 Subject: [PATCH 027/205] New feature operation time for MiElHVAC (#22334) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes --- .../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index 1d9cd0ced..12da53937 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -87,11 +87,15 @@ struct miel_hvac_data_roomtemp { uint8_t temp; uint8_t _pad2[2]; uint8_t temp05; + uint8_t settemp; + uint8_t _pad3[3]; + uint8_t opratingtime; + uint8_t opratingtime1; + uint8_t opratingtime2; }; struct miel_hvac_data_status { - uint8_t _pad1[2]; - uint8_t _pad2[1]; + uint8_t _pad1[3]; uint8_t compressor; #define MIEL_HVAC_STATUS_COMPRESSOR_OFF 0x00 #define MIEL_HVAC_STATUS_COMPRESSOR_ON 0x01 @@ -135,6 +139,10 @@ CTASSERT(offsetof(struct miel_hvac_data, data.settings.airdirection) == 14); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.temp) == 3); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.temp05) == 6); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.settemp) == 7); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.opratingtime) == 11); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.opratingtime1) == 12); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.opratingtime2) == 13); CTASSERT(offsetof(struct miel_hvac_data, data.status.compressor) == 4); CTASSERT(offsetof(struct miel_hvac_data, data.status.operationpower) == 5); @@ -1345,6 +1353,17 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) } ResponseAppend_P(PSTR(",\"Temperature\":\"%s\""), room_temp); + + uint32_t combined_time = ((uint32_t)rt->opratingtime << 16) | ((uint32_t)rt->opratingtime1 << 8) | (uint32_t)rt->opratingtime2; + float operationtime_in_min = (float)combined_time; + char operationtime[33]; + dtostrf(operationtime_in_min, 1, 0, operationtime); + ResponseAppend_P(PSTR(",\"OperationTime\":\"%s\""), + operationtime); + + ResponseAppend_P(PSTR(",\"RoomTemp\":\"%s\""), + ToHex_P((uint8_t *)&sc->sc_temp, sizeof(sc->sc_temp), + hex, sizeof(hex))); } if (sc->sc_status.type != 0) { @@ -1370,15 +1389,7 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) dtostrfd((float)operationenergy_in_kWh, 1, operationenergy); ResponseAppend_P(PSTR(",\"OperationEnergy\":\"%s\""), operationenergy); - } - if (sc->sc_temp.type != 0) { - ResponseAppend_P(PSTR(",\"RoomTemp\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_temp, sizeof(sc->sc_temp), - hex, sizeof(hex))); - } - - if (sc->sc_status.type != 0) { ResponseAppend_P(PSTR(",\"Status\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_status, sizeof(sc->sc_status), hex, sizeof(hex))); From 02972ad3ea5e97eefbfc5bb7f317853a45f757d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20Zi=C3=B3=C5=82kowski?= Date: Tue, 22 Oct 2024 16:35:16 +0200 Subject: [PATCH 028/205] Create Panlee_ZX4D30NE01S-UR_SC-02_no_touch.display.ini (#22344) --- .../Panlee_ZX4D30NE01S-UR_SC-02_no_touch.display.ini | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tasmota/displaydesc/Panlee_ZX4D30NE01S-UR_SC-02_no_touch.display.ini diff --git a/tasmota/displaydesc/Panlee_ZX4D30NE01S-UR_SC-02_no_touch.display.ini b/tasmota/displaydesc/Panlee_ZX4D30NE01S-UR_SC-02_no_touch.display.ini new file mode 100644 index 000000000..9870fa0df --- /dev/null +++ b/tasmota/displaydesc/Panlee_ZX4D30NE01S-UR_SC-02_no_touch.display.ini @@ -0,0 +1,5 @@ +:H,ZX4D30NE01S-UR,480,272,16,RGB,40,48,47,14,45,9,10,11,12,13,16,17,18,8,3,46,42,5,6,7,15 +:V,1,20,10,30,1,10,10,30,0 +:S,2,1,1,0,40,20 +:B,120,02 +# From 5200aca185edfd0f72bcf3808af0e194a8f6c262 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Wed, 23 Oct 2024 16:07:30 +0200 Subject: [PATCH 029/205] New feature Outdoor Temperature for MiElHVAC (#22345) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes * New feature Outdoor Temperature for MiElHVAC * Add Outdoor Temperature --- .../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index 12da53937..84aa93f37 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -85,7 +85,8 @@ struct miel_hvac_data_settings { struct miel_hvac_data_roomtemp { uint8_t _pad1[2]; uint8_t temp; - uint8_t _pad2[2]; + uint8_t _pad2[1]; + uint8_t outdoortemp; uint8_t temp05; uint8_t settemp; uint8_t _pad3[3]; @@ -138,6 +139,7 @@ CTASSERT(offsetof(struct miel_hvac_data, data.settings.temp05) == 11); CTASSERT(offsetof(struct miel_hvac_data, data.settings.airdirection) == 14); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.temp) == 3); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.outdoortemp) == 5); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.temp05) == 6); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.settemp) == 7); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.opratingtime) == 11); @@ -292,6 +294,13 @@ miel_hvac_roomtemp2deg(uint8_t roomtemp) } } +static inline float +miel_hvac_outdoortemp2deg(uint8_t outdoortemp) +{ + outdoortemp -= 128; + return ((float) outdoortemp/2); +} + struct miel_hvac_msg_remotetemp { uint8_t seven; uint8_t control; @@ -1354,6 +1363,14 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) ResponseAppend_P(PSTR(",\"Temperature\":\"%s\""), room_temp); + if(rt->outdoortemp > 1) { + char outdoor_temp[33]; + float temp = miel_hvac_outdoortemp2deg(rt->outdoortemp); + dtostrfd(ConvertTemp(temp), 1, outdoor_temp); + ResponseAppend_P(PSTR(",\"OutdoorTemperature\":\"%s\""), + outdoor_temp); + } + uint32_t combined_time = ((uint32_t)rt->opratingtime << 16) | ((uint32_t)rt->opratingtime1 << 8) | (uint32_t)rt->opratingtime2; float operationtime_in_min = (float)combined_time; char operationtime[33]; From 7f6dbfbeac59eed4dca6ae086b80ece7c9a2c6e1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:12:20 +0200 Subject: [PATCH 030/205] Update changelogs --- CHANGELOG.md | 2 ++ RELEASENOTES.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e92ca932b..c9e67e918 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups - DALI command `DaliTarget` to set light control broadcast, group number or gear number +- Mitsubishi Electric HVAC Operation time for MiElHVAC (#22334) +- Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC (#22345) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 21fe02b4e..325a6c26b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -120,6 +120,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups - DALI command `DaliTarget` to set light control broadcast, group number or gear number +- Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) +- Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) ### Breaking Changed From 73897ef7558a25bcdb8d4b0e909f41e53451b515 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 23 Oct 2024 20:44:25 +0200 Subject: [PATCH 031/205] Back to three esp32x frameworks... (#22351) * add special frameworks * Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- pio-tools/post_esp32.py | 32 +++++++++++++++++++++++++++----- platformio_tasmota32.ini | 2 +- platformio_tasmota_env32.ini | 10 +++------- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e8df939fe..4d1fe4601 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.8 - - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241015 + - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241023 - [ ] 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/pio-tools/post_esp32.py b/pio-tools/post_esp32.py index f0af4322a..e296be29e 100644 --- a/pio-tools/post_esp32.py +++ b/pio-tools/post_esp32.py @@ -43,14 +43,30 @@ variant = env.BoardConfig().get("build.variant", "") sections = env.subst(env.get("FLASH_EXTRA_IMAGES")) chip = env.get("BOARD_MCU") mcu_build_variant = env.BoardConfig().get("build.variant", "").lower() -FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") # Copy safeboots firmwares in place when running in Github github_actions = os.getenv('GITHUB_ACTIONS') -if github_actions and os.path.exists("./firmware/firmware"): - shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduinoespressif32/variants/tasmota", dirs_exist_ok=True) - if variants_dir: - shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) +extra_flags = ''.join([element.replace("-D", " ") for element in env.BoardConfig().get("build.extra_flags", "")]) +build_flags = ''.join([element.replace("-D", " ") for element in env.GetProjectOption("build_flags")]) + +if "CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags: + FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-solo1") + if github_actions and os.path.exists("./firmware/firmware"): + shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-solo1/variants/tasmota") + if variants_dir: + shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) +elif "CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags: + FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-ITEAD") + if github_actions and os.path.exists("./firmware/firmware"): + shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-ITEAD/variants/tasmota") + if variants_dir: + shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) +else: + FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") + if github_actions and os.path.exists("./firmware/firmware"): + shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduinoespressif32/variants/tasmota") + if variants_dir: + shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) # Copy pins_arduino.h to variants folder if variants_dir: @@ -113,6 +129,12 @@ def patch_partitions_bin(size_string): def esp32_create_chip_string(chip): tasmota_platform_org = env.subst("$BUILD_DIR").split(os.path.sep)[-1] tasmota_platform = tasmota_platform_org.split('-')[0] + if ("CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags) and "tasmota32-safeboot" not in tasmota_platform_org and "tasmota32solo1" not in tasmota_platform_org: + print(Fore.YELLOW + "Unexpected naming convention in this build environment:" + Fore.RED, tasmota_platform_org) + print(Fore.YELLOW + "Expected build environment name like " + Fore.GREEN + "'tasmota32solo1-whatever-you-want'") + print(Fore.YELLOW + "Please correct your actual build environment, to avoid undefined behavior in build process!!") + tasmota_platform = "tasmota32solo1" + return tasmota_platform if "tasmota" + chip[3:] not in tasmota_platform: # check + fix for a valid name like 'tasmota' + '32c3' tasmota_platform = "tasmota" + chip[3:] if "-DUSE_USB_CDC_CONSOLE" not in env.BoardConfig().get("build.extra_flags"): diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 15b19d401..9a5d99ef1 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -80,7 +80,7 @@ lib_ignore = ${esp32_defaults.lib_ignore} ccronexpr [core32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.10.30/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.10.31/platform-espressif32.zip platform_packages = build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index f5dc5931a..5b6baa383 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -31,11 +31,11 @@ extends = env:tasmota32_base board = esp32-solo1 board_build.app_partition_name = safeboot build_flags = ${env:tasmota32_base.build_flags} + -DFRAMEWORK_ARDUINO_SOLO1 -DFIRMWARE_SAFEBOOT -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-safeboot.bin"' lib_extra_dirs = lib/lib_ssl, lib/libesp32 lib_ignore = ${safeboot_flags.lib_ignore} -custom_sdkconfig = CONFIG_FREERTOS_UNICORE=y [env:tasmota32solo1-safeboot] extends = env:tasmota32_base @@ -46,7 +46,6 @@ build_flags = ${env:tasmota32_base.build_flags} -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32solo1-safeboot.bin"' lib_extra_dirs = lib/lib_ssl, lib/libesp32 lib_ignore = ${safeboot_flags.lib_ignore} -custom_sdkconfig = CONFIG_FREERTOS_UNICORE=y [env:tasmota32s2-safeboot] extends = env:tasmota32_base @@ -154,7 +153,6 @@ build_flags = ${env:tasmota32_base.build_flags} lib_ignore = ${env:tasmota32_base.lib_ignore} Micro-RTSP epdiy -custom_sdkconfig = CONFIG_FREERTOS_UNICORE=y [env:tasmota32s2] extends = env:tasmota32_base @@ -266,6 +264,7 @@ board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv build_flags = ${env:tasmota32_base.build_flags} -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-zbbrdgpro.bin"' -DFIRMWARE_ZBBRDGPRO + -DFRAMEWORK_ARDUINO_ITEAD custom_files_upload = ${env:tasmota32_base.custom_files_upload} tools/fw_SonoffZigbeeBridgePro_cc2652/Sonoff_ZBPro.autoconf tasmota/berry/zigbee/cc2652_flasher.be @@ -278,16 +277,13 @@ lib_ignore = ${env:tasmota32_base.lib_ignore} IRremoteESP8266 TasmotaModbus ESP Mail Client -custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 - CONFIG_D0WD_PSRAM_CS_IO=18 [env:tasmota32-nspanel] extends = env:tasmota32_base build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_NSPANEL + -DFRAMEWORK_ARDUINO_ITEAD -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin"' -custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 - CONFIG_D0WD_PSRAM_CS_IO=18 [env:tasmota32-AD] extends = env:tasmota32_base From fd37801d533494d4d7048b40f7bca874fcd4c2e5 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Thu, 24 Oct 2024 10:06:04 +0200 Subject: [PATCH 032/205] Optimized behavior to publish shutter data with sensor request (#22353) * avoid shutter sensor data published ever * avoid shutter data report on sensor trigger --- .../xdrv_27_esp32_shutter.ino | 36 +++++++++++-------- .../tasmota_xdrv_driver/xdrv_27_shutter.ino | 26 +++++++++----- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index 954633c21..cff8dc1f8 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -195,6 +195,7 @@ struct SHUTTERGLOBAL { bool callibration_run = false; // if true a callibration is running and additional measures are captured uint8_t stopp_armed = 0; // Count each step power usage is below limit of 1 Watt uint16_t cycle_time = 0; // used for shuttersetup to get accurate timing + bool sensor_data_reported = false; // ensure that shutter sensor data reported every sedond is only reported if shutter is moving and there is a change. } ShutterGlobal; #define SHT_DIV_ROUND(__A, __B) (((__A) + (__B)/2) / (__B)) @@ -946,7 +947,7 @@ void ShutterRelayChanged(void) void ShutterReportPosition(bool always, uint32_t index) { - Response_P(PSTR("{")); + uint32_t i = 0; uint32_t n = TasmotaGlobal.shutters_present; uint8_t shutter_running = 0; @@ -958,7 +959,7 @@ void ShutterReportPosition(bool always, uint32_t index) // Allow function exit if nothing to report (99.9% use case) if (!always && !shutter_running) return; - + Response_P(PSTR("{")); if( index != MAX_SHUTTERS_ESP32) { i = index; n = index+1; @@ -976,7 +977,7 @@ void ShutterReportPosition(bool always, uint32_t index) uint32_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); uint32_t target = ShutterRealToPercentPosition(Shutter[i].target_position, i); ResponseAppend_P(JSON_SHUTTER_POS, i + 1, (ShutterSettings.shutter_options[i] & 1) ? 100 - position : position, Shutter[i].direction,(ShutterSettings.shutter_options[i] & 1) ? 100 - target : target, Shutter[i].tilt_real_pos ); - } + } ResponseJsonEnd(); if (always || shutter_running) { MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); // RulesProcess() now re-entry protected @@ -1196,6 +1197,7 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) Shutter[i].target_position = target_pos; Shutter[i].start_position = Shutter[i].real_position; TasmotaGlobal.rules_flag.shutter_moving = 1; + ShutterGlobal.sensor_data_reported = false; ShutterAllowPreStartProcedure(i); Shutter[i].time = Shutter[i].last_reported_time = 0; @@ -2330,18 +2332,24 @@ bool Xdrv27(uint32_t function) } break; case FUNC_JSON_APPEND: - for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) { - ResponseAppend_P(","); - uint8_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); - position = (ShutterSettings.shutter_options[i] & 1) ? 100 - position : position; - uint8_t target = ShutterRealToPercentPosition(Shutter[i].target_position, i); - target = (ShutterSettings.shutter_options[i] & 1) ? 100 - target : target; - ResponseAppend_P(JSON_SHUTTER_POS, i + 1, position, Shutter[i].direction, target, Shutter[i].tilt_real_pos ); -#ifdef USE_DOMOTICZ - if ((0 == TasmotaGlobal.tele_period) && (0 == i)) { - DomoticzSensor(DZ_SHUTTER, position); + if (!ShutterGlobal.sensor_data_reported) { + ShutterGlobal.sensor_data_reported = true; + for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) { + ResponseAppend_P(","); + uint8_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); + position = (ShutterSettings.shutter_options[i] & 1) ? 100 - position : position; + uint8_t target = ShutterRealToPercentPosition(Shutter[i].target_position, i); + target = (ShutterSettings.shutter_options[i] & 1) ? 100 - target : target; + ResponseAppend_P(JSON_SHUTTER_POS, i + 1, position, Shutter[i].direction, target, Shutter[i].tilt_real_pos ); + if (Shutter[i].direction != 0) { + ShutterGlobal.sensor_data_reported = false; + } + #ifdef USE_DOMOTICZ + if ((0 == TasmotaGlobal.tele_period) && (0 == i)) { + DomoticzSensor(DZ_SHUTTER, position); + } + #endif // USE_DOMOTICZ } -#endif // USE_DOMOTICZ } break; case FUNC_SET_POWER: diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 491081904..e433134d5 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -52,6 +52,7 @@ int32_t current_stop_way = 0; int32_t next_possible_stop_position = 0; int32_t current_real_position = 0; int32_t current_pwm_velocity = 0; +bool sensor_data_reported = false; const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM = "" @@ -772,6 +773,7 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) Shutter[i].target_position = target_pos; Shutter[i].start_position = Shutter[i].real_position; TasmotaGlobal.rules_flag.shutter_moving = 1; + sensor_data_reported = false; ShutterAllowPreStartProcedure(i); Shutter[i].time = Shutter[i].last_reported_time = 0; @@ -1928,16 +1930,22 @@ bool Xdrv27(uint32_t function) } break; case FUNC_JSON_APPEND: - for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) { - uint8_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); - uint8_t target = ShutterRealToPercentPosition(Shutter[i].target_position, i); - ResponseAppend_P(","); - ResponseAppend_P(JSON_SHUTTER_POS, i+1, (Settings->shutter_options[i] & 1) ? 100 - position : position, Shutter[i].direction,(Settings->shutter_options[i] & 1) ? 100 - target : target, Shutter[i].tilt_real_pos ); -#ifdef USE_DOMOTICZ - if ((0 == TasmotaGlobal.tele_period) && (0 == i)) { - DomoticzSensor(DZ_SHUTTER, position); + if (!sensor_data_reported) { + sensor_data_reported = true; + for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) { + uint8_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); + uint8_t target = ShutterRealToPercentPosition(Shutter[i].target_position, i); + ResponseAppend_P(","); + ResponseAppend_P(JSON_SHUTTER_POS, i+1, (Settings->shutter_options[i] & 1) ? 100 - position : position, Shutter[i].direction,(Settings->shutter_options[i] & 1) ? 100 - target : target, Shutter[i].tilt_real_pos ); + if (Shutter[i].direction != 0) { + sensor_data_reported = false; + } + #ifdef USE_DOMOTICZ + if ((0 == TasmotaGlobal.tele_period) && (0 == i)) { + DomoticzSensor(DZ_SHUTTER, (Settings->shutter_options[i] & 1) ? 100 - position : position); + } + #endif // USE_DOMOTICZ } -#endif // USE_DOMOTICZ } break; case FUNC_SET_POWER: From e4f431dc7b0bc6b9c013dae2ec595aeb23a82426 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Thu, 24 Oct 2024 10:06:48 +0200 Subject: [PATCH 033/205] New feature Compressor Frequency for MiElHVAC (#22347) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes * New feature Outdoor Temperature for MiElHVAC * Add Outdoor Temperature * New feature Compressor Frequency for MiElHVAC * Added Outdoor Temperature * Renamed internal properties due typo operating and oprating to operation --- .../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index 84aa93f37..658796102 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -90,13 +90,14 @@ struct miel_hvac_data_roomtemp { uint8_t temp05; uint8_t settemp; uint8_t _pad3[3]; - uint8_t opratingtime; - uint8_t opratingtime1; - uint8_t opratingtime2; + uint8_t operationtime; + uint8_t operationtime1; + uint8_t operationtime2; }; struct miel_hvac_data_status { - uint8_t _pad1[3]; + uint8_t _pad1[2]; + uint8_t compressorfrequency; uint8_t compressor; #define MIEL_HVAC_STATUS_COMPRESSOR_OFF 0x00 #define MIEL_HVAC_STATUS_COMPRESSOR_ON 0x01 @@ -142,10 +143,11 @@ CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.temp) == 3); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.outdoortemp) == 5); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.temp05) == 6); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.settemp) == 7); -CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.opratingtime) == 11); -CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.opratingtime1) == 12); -CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.opratingtime2) == 13); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime) == 11); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime1) == 12); +CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime2) == 13); +CTASSERT(offsetof(struct miel_hvac_data, data.status.compressorfrequency) == 3); CTASSERT(offsetof(struct miel_hvac_data, data.status.compressor) == 4); CTASSERT(offsetof(struct miel_hvac_data, data.status.operationpower) == 5); CTASSERT(offsetof(struct miel_hvac_data, data.status.operationpower1) == 6); @@ -1371,7 +1373,7 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) outdoor_temp); } - uint32_t combined_time = ((uint32_t)rt->opratingtime << 16) | ((uint32_t)rt->opratingtime1 << 8) | (uint32_t)rt->opratingtime2; + uint32_t combined_time = ((uint32_t)rt->operationtime << 16) | ((uint32_t)rt->operationtime1 << 8) | (uint32_t)rt->operationtime2; float operationtime_in_min = (float)combined_time; char operationtime[33]; dtostrf(operationtime_in_min, 1, 0, operationtime); @@ -1389,10 +1391,14 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) name = miel_hvac_map_byval(status->compressor, miel_hvac_compressor_map, nitems(miel_hvac_compressor_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"Compressor\":\"%s\""), - name); - } + ResponseAppend_P(PSTR(",\"Compressor\":\"%s\""), + name != NULL ? name : "N/A"); + + unsigned int compressor_frequency = status->compressorfrequency; + char compressorfrequency[33]; + utoa(compressor_frequency, compressorfrequency, 10); + ResponseAppend_P(PSTR(",\"CompressorFrequency\":\"%s\""), + compressorfrequency); uint16_t combined_power = ((uint16_t)status->operationpower << 8) | (uint16_t)status->operationpower1; char operationpower[33]; From bbba5b919601d2bf3331a66d534206d2ee01b795 Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Thu, 24 Oct 2024 10:08:00 +0200 Subject: [PATCH 034/205] [SolaxX1] Add meter mode (#22330) --- .../tasmota_xdrv_driver/xdrv_03_energy.ino | 3 +- .../xdrv_03_esp32_energy.ino | 3 +- .../tasmota_xnrg_energy/xnrg_12_solaxX1.ino | 238 +++++++++++++++--- 3 files changed, 206 insertions(+), 38 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino index 6b2f992d3..eb07c4fb2 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino @@ -1514,9 +1514,10 @@ bool Xdrv03(uint32_t function) case FUNC_SLEEP_LOOP: XnrgCall(FUNC_LOOP); break; + case FUNC_EVERY_100_MSECOND: case FUNC_EVERY_250_MSECOND: if (TasmotaGlobal.uptime > 4) { - XnrgCall(FUNC_EVERY_250_MSECOND); + XnrgCall(function); } break; case FUNC_EVERY_SECOND: diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index 536301409..26e7ec27f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -1916,9 +1916,10 @@ bool Xdrv03(uint32_t function) case FUNC_SLEEP_LOOP: XnrgCall(FUNC_LOOP); break; + case FUNC_EVERY_100_MSECOND: case FUNC_EVERY_250_MSECOND: if (TasmotaGlobal.uptime > 4) { - XnrgCall(FUNC_EVERY_250_MSECOND); + XnrgCall(function); } break; case FUNC_EVERY_SECOND: diff --git a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino index ec9ee7cd5..29185eab1 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino @@ -37,9 +37,10 @@ #define D_SOLAX_X1 "SolaxX1" #include +TasmotaSerial *solaxX1Serial; const char kSolaxMode[] PROGMEM = - D_OFF "|" D_SOLAX_MODE_0 "|" D_SOLAX_MODE_1 "|" D_SOLAX_MODE_2 "|" D_SOLAX_MODE_3 "|" D_SOLAX_MODE_4 "|" + D_GATEWAY "|" D_OFF "|" D_SOLAX_MODE_0 "|" D_SOLAX_MODE_1 "|" D_SOLAX_MODE_2 "|" D_SOLAX_MODE_3 "|" D_SOLAX_MODE_4 "|" D_SOLAX_MODE_5 "|" D_SOLAX_MODE_6; const char kSolaxError[] PROGMEM = @@ -118,6 +119,10 @@ struct SOLAXX1_GLOBALDATA { uint8_t QueryID_count = 240; bool Command_QueryID = false;; bool Command_QueryConfig = false; + bool MeterMode = false; + float MeterPower = 5000; + float MeterImport; + float MeterExport; } solaxX1_global; struct SOLAXX1_SENDDATA { @@ -130,8 +135,6 @@ struct SOLAXX1_SENDDATA { uint8_t Payload[16] = {0x00}; } solaxX1_SendData; -TasmotaSerial *solaxX1Serial; - /*********************************************************************************************/ void solaxX1_RS485Send(void) { @@ -143,27 +146,84 @@ void solaxX1_RS485Send(void) { memcpy(message + 7, solaxX1_SendData.FunctionCode, 1); memcpy(message + 8, solaxX1_SendData.DataLength, 1); memcpy(message + 9, solaxX1_SendData.Payload, sizeof(solaxX1_SendData.Payload)); - uint16_t crc = solaxX1_calculateCRC(message, 9 + solaxX1_SendData.DataLength[0]); // calculate out crc bytes - while (solaxX1Serial->available() > 0) { // read serial if any old data is available + solaxX1_RS485SendRaw(message, 9 + solaxX1_SendData.DataLength[0], 0); +} + +void solaxX1_RS485SendMeterFloat(float Value) { + uint8_t MeterResponse[7] = {0x01, 0x04, 0x04, 0x00}; + for (uint8_t i = 0; i <= 3; i++) { // Store bytes in reverse order + MeterResponse[i + 3] = *((char*)(&Value) + 3 - i); + } + solaxX1_RS485SendRaw(MeterResponse, 7, 1); +} + +void solaxX1_RS485SendMeterInt16(int16_t Value) { + uint8_t MeterResponse[5] = {0x01, 0x03, 0x02, 0x00}; + MeterResponse[3] = highByte(Value); + MeterResponse[4] = lowByte(Value); + solaxX1_RS485SendRaw(MeterResponse, 5, 1); +} + +void solaxX1_RS485SendMeterTotalInt(uint32_t Export, uint32_t Import) { + uint8_t MeterResponse[11] = {0x01, 0x03, 0x08, 0x00}; + for (uint8_t i = 0; i <= 3; i++) { // Store bytes in reverse order + MeterResponse[i + 3] = *((char*)(&Export) + 3 - i); + } + for (uint8_t i = 0; i <= 3; i++) { // Store bytes in reverse order + MeterResponse[i + 7] = *((char*)(&Import) + 3 - i); + } + solaxX1_RS485SendRaw(MeterResponse, 11, 1); +} + +void solaxX1_RS485SendRaw(uint8_t *SendBuffer, uint8_t DataLen, uint8_t CRCflag) { + uint16_t crc; + while (solaxX1Serial->available()) { // read serial if any old data is available solaxX1Serial->read(); } - if (PinUsed(GPIO_SOLAXX1_RTS)) { - digitalWrite(Pin(GPIO_SOLAXX1_RTS), HIGH); + if (PinUsed(GPIO_SOLAXX1_RTS)) digitalWrite(Pin(GPIO_SOLAXX1_RTS), HIGH); + solaxX1Serial->flush(); + solaxX1Serial->write(SendBuffer, DataLen); + if (CRCflag) { + crc = solaxX1_calculateCRC_MBUS(SendBuffer, DataLen); // Use CRC MBUS algorithm + solaxX1Serial->write(lowByte(crc)); + solaxX1Serial->write(highByte(crc)); + } else { + crc = solaxX1_calculateCRC(SendBuffer, DataLen); // Use CRC Solax algorithm + solaxX1Serial->write(highByte(crc)); + solaxX1Serial->write(lowByte(crc)); } solaxX1Serial->flush(); - solaxX1Serial->write(message, 9 + solaxX1_SendData.DataLength[0]); - solaxX1Serial->write(highByte(crc)); - solaxX1Serial->write(lowByte(crc)); - solaxX1Serial->flush(); - if (PinUsed(GPIO_SOLAXX1_RTS)) { - digitalWrite(Pin(GPIO_SOLAXX1_RTS), LOW); - } - AddLogBuffer(LOG_LEVEL_DEBUG_MORE, message, 9 + solaxX1_SendData.DataLength[0]); + if (PinUsed(GPIO_SOLAXX1_RTS)) digitalWrite(Pin(GPIO_SOLAXX1_RTS), LOW); + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, SendBuffer, DataLen); } bool solaxX1_RS485Receive(uint8_t *ReadBuffer) { + uint32_t SerWatchdogTime; + + // Read header uint8_t len = 0; - while (solaxX1Serial->available() > 0) { + SerWatchdogTime = millis(); + while (len < 2) { // read exact length because of unaccurate timing of the inverter + if (solaxX1Serial->available()) ReadBuffer[len++] = (uint8_t)solaxX1Serial->read(); + if (millis() > (SerWatchdogTime + 1000)) return true; // No data received -> bail out + } + + // Check and set meter mode + solaxX1_SwitchMeterMode((ReadBuffer[0] == 0x01 || ReadBuffer[0] == 0x02) && (ReadBuffer[1] == 0x03 || ReadBuffer[1] == 0x04)); + + // Read data in meter mode + if (solaxX1_global.MeterMode) { // Metermode + SerWatchdogTime = millis(); + while (len < 8) { // read exact length because of unaccurate timing of the inverter + if (solaxX1Serial->available()) ReadBuffer[len++] = (uint8_t)solaxX1Serial->read(); + if (millis() > (SerWatchdogTime + 1000)) return true; // No data received -> bail out + } + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, ReadBuffer, len); + return false; // Ignore checksum + } // end Metermode + + // Process normal receive + while (solaxX1Serial->available()) { ReadBuffer[len++] = (uint8_t)solaxX1Serial->read(); } AddLogBuffer(LOG_LEVEL_DEBUG_MORE, ReadBuffer, len); @@ -175,11 +235,27 @@ uint16_t solaxX1_calculateCRC(uint8_t *bExternTxPackage, uint8_t bLen) { uint8_t i; uint16_t wChkSum = 0; for (i = 0; i < bLen; i++) { - wChkSum = wChkSum + bExternTxPackage[i]; + wChkSum += bExternTxPackage[i]; } return wChkSum; } +uint16_t solaxX1_calculateCRC_MBUS(uint8_t *frame, uint8_t Len) { + uint16_t crc = 0xFFFF; + for (uint32_t i = 0; i < Len; i++) { + crc ^= frame[i]; + for (uint32_t j = 8; j; j--) { + if ((crc & 0x0001) != 0) { // If the LSB is set + crc >>= 1; // Shift right and XOR 0xA001 + crc ^= 0xA001; + } else { // Else LSB is not set + crc >>= 1; // Just shift right + } + } + } + return crc; +} + void solaxX1_ExtractText(uint8_t *DataIn, uint8_t *DataOut, uint8_t Begin, uint8_t End) { uint8_t i; for (i = Begin; i <= End; i++) { @@ -253,27 +329,78 @@ uint8_t solaxX1_ParseErrorCode(uint32_t code) { return 0; } +void solaxX1_SwitchMeterMode(bool MeterMode) { + if (solaxX1_global.MeterMode == MeterMode) return; + solaxX1_global.MeterMode = MeterMode; + if (MeterMode) { + Energy->data_valid[0] = ENERGY_WATCHDOG; + solaxX1.runMode = -2; + solaxX1.temperature = solaxX1.dc1_voltage = solaxX1.dc1_current = solaxX1.dc1_power = solaxX1.dc2_voltage = solaxX1.dc2_current = solaxX1.dc2_power = 0; + } else { + solaxX1.runMode = -1; + } +} + /*********************************************************************************************/ -void solaxX1_250MSecond(void) { // Every 250 milliseconds +void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds uint8_t DataRead[80] = {0}; uint8_t TempData[16] = {0}; char TempDataChar[32]; float TempFloat; + static uint32_t LastMeterTime; + static uint16_t MtrReg, MtrPwr32, MtrPwr16, MtrImp32, MtrExp32, MrtTot64, MtrRest; if (solaxX1Serial->available()) { - if (solaxX1_RS485Receive(DataRead)) { // CRC-error -> no further action - DEBUG_SENSOR_LOG(PSTR("SX1: Data response CRC error")); + if (solaxX1_RS485Receive(DataRead)) { // CRC or other error -> no further action + AddLog(LOG_LEVEL_ERROR, PSTR("SX1: (CRC) error in received data")); return; } - solaxX1_global.SendRetry_count = 20; // Inverter is responding - - if (DataRead[0] != 0xAA || DataRead[1] != 0x55) { // Check for header - DEBUG_SENSOR_LOG(PSTR("SX1: Check for header failed")); + if (solaxX1_global.MeterMode) { // Metermode + AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: Metermode %02X %02X xx %02X"), DataRead[0], DataRead[1], DataRead[3]); + LastMeterTime = TasmotaGlobal.uptime; + if (DataRead[0] != 0x01) return; // Respond only to requests for meter #1 + switch (DataRead[3]) { + case 0x0B: // received "Register meter request" + //solaxX1_RS485SendMeterInt16(0); // Tell inverter to request int16 values + solaxX1_RS485SendMeterInt16(0xa8); // Tell inverter to request float32 values + MtrReg++; + break; + case 0x0C: // received "Power request (32 bit float)" + solaxX1_RS485SendMeterFloat(solaxX1_global.MeterPower); + MtrPwr32++; + break; + case 0x0E: // received "Power request (16 bit int)" + solaxX1_RS485SendMeterInt16((int16_t)solaxX1_global.MeterPower); + MtrPwr16++; + break; + case 0x48: // received "Import request (32 bit float)" + solaxX1_RS485SendMeterFloat(solaxX1_global.MeterImport); + MtrImp32++; + break; + case 0x4A: // received "Export request (32 bit float)" + solaxX1_RS485SendMeterFloat(solaxX1_global.MeterExport); + MtrExp32++; + break; + case 0x08: // received "Energy total request (2*32 bit uint)" + solaxX1_RS485SendMeterTotalInt((uint32_t)(solaxX1_global.MeterExport * 100.0), (uint32_t)(solaxX1_global.MeterImport * 100.0)); + MrtTot64++; + break; + default: + MtrRest++; + } + AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: MtrReg %d, MtrPwr32 %d, MtrPwr16 %d, MtrImp32 %d, MtrExp32 %d, MrtTot64 %d, MtrRest %d"), MtrReg, MtrPwr32, MtrPwr16, MtrImp32, MtrExp32, MrtTot64, MtrRest); return; } + if (DataRead[0] != 0xAA || DataRead[1] != 0x55) { // Check for header + AddLog(LOG_LEVEL_ERROR, PSTR("SX1: Header check failed: %02X %02X"), DataRead[0], DataRead[1]); + return; + } + + solaxX1_global.SendRetry_count = 20; // Inverter is responding + if (DataRead[6] == 0x11 && DataRead[7] == 0x82) { // received "Response for query (live data)" Energy->data_valid[0] = 0; solaxX1.temperature = (DataRead[9] << 8) | DataRead[10]; // Temperature @@ -416,6 +543,11 @@ void solaxX1_250MSecond(void) { // Every 250 milliseconds } // end solaxX1Serial->available() + if(solaxX1_global.MeterMode) { + if (TasmotaGlobal.uptime > LastMeterTime + 20) solaxX1_SwitchMeterMode(false); // Switch back to normal mode, when no Meter request is received for 20 sec. + return; + } + // DEBUG_SENSOR_LOG(PSTR("SX1: solaxX1_global.AddressAssigned: %d, solaxX1_global.QueryData_count: %d, solaxX1_global.SendRetry_count: %d, solaxX1_global.QueryID_count: %d"), solaxX1_global.AddressAssigned, solaxX1_global.QueryData_count, solaxX1_global.SendRetry_count, solaxX1_global.QueryID_count); if (solaxX1_global.AddressAssigned) { if (!solaxX1_global.QueryData_count) { // normal periodically query @@ -437,13 +569,13 @@ void solaxX1_250MSecond(void) { // Every 250 milliseconds solaxX1_global.SendRetry_count = 20; DEBUG_SENSOR_LOG(PSTR("SX1: Inverter went \"off\"")); Energy->data_valid[0] = ENERGY_WATCHDOG; - solaxX1.temperature = solaxX1.dc1_voltage = solaxX1.dc2_voltage = solaxX1.dc1_current = solaxX1.dc2_current = solaxX1.dc1_power = 0; - solaxX1.dc2_power = Energy->current[0] = Energy->voltage[0] = Energy->frequency[0] = Energy->active_power[0] = 0; + solaxX1.temperature = solaxX1.dc1_voltage = solaxX1.dc1_current = solaxX1.dc1_power = solaxX1.dc2_voltage = solaxX1.dc2_current = solaxX1.dc2_power = 0; solaxX1.runMode = -1; // off(line) solaxX1_global.AddressAssigned = false; } // end Inverter went "off" } else { // sent query for inverters in offline status if (!solaxX1_global.SendRetry_count) { + solaxX1_global.Command_QueryConfig = solaxX1_global.Command_QueryID = false; // Clear commands to be sure solaxX1_global.SendRetry_count = 20; DEBUG_SENSOR_LOG(PSTR("SX1: Sent query for inverters in offline state")); solaxX1_QueryOfflineInverters(); @@ -451,7 +583,7 @@ void solaxX1_250MSecond(void) { // Every 250 milliseconds } solaxX1_global.SendRetry_count--; return; -} // end solaxX1_250MSecond +} // end solaxX1_CyclicTask void solaxX1_SnsInit(void) { AddLog(LOG_LEVEL_INFO, PSTR("SX1: Init - RX-pin: %d, TX-pin: %d, RTS-pin: %d"), Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), Pin(GPIO_SOLAXX1_RTS)); @@ -461,22 +593,40 @@ void solaxX1_SnsInit(void) { #ifdef ESP32 AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: Serial UART%d"), solaxX1Serial->getUart()); #endif + if (PinUsed(GPIO_SOLAXX1_RTS)) pinMode(Pin(GPIO_SOLAXX1_RTS), OUTPUT); } else { TasmotaGlobal.energy_driver = ENERGY_NONE; } - if (PinUsed(GPIO_SOLAXX1_RTS)) { - pinMode(Pin(GPIO_SOLAXX1_RTS), OUTPUT); - } } void solaxX1_DrvInit(void) { if (PinUsed(GPIO_SOLAXX1_RX) && PinUsed(GPIO_SOLAXX1_TX)) { TasmotaGlobal.energy_driver = XNRG_12; Energy->type_dc = true; // Handle like DC, because U*I from inverter is not valid for apparent power; U*I could be lower than active power + Energy->frequency[0] = 0; // Set value, to make frequency present in output } } bool SolaxX1_cmd(void) { + if (Energy->command_code != CMND_ENERGYCONFIG) return false; // Process unchanged data + + if (!strncasecmp(XdrvMailbox.data, "MeterPower", 10)) { + solaxX1_global.MeterPower = CharToFloat(&XdrvMailbox.data[11]); + ResponseCmndFloat(solaxX1_global.MeterPower, 1); + AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: MeterPower: %3_f"), &solaxX1_global.MeterPower); + return false; + } else if (!strncasecmp(XdrvMailbox.data, "MeterImport", 11)) { + solaxX1_global.MeterImport = CharToFloat(&XdrvMailbox.data[12]); + ResponseCmndFloat(solaxX1_global.MeterImport, 8); + AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: MeterImport: %3_f"), &solaxX1_global.MeterImport); + return false; + } else if (!strncasecmp(XdrvMailbox.data, "MeterExport", 11)) { + solaxX1_global.MeterExport = CharToFloat(&XdrvMailbox.data[12]); + ResponseCmndFloat(solaxX1_global.MeterExport, 8); + AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: MeterExport: %3_f"), &solaxX1_global.MeterExport); + return false; + } + if (!solaxX1_global.AddressAssigned) { AddLog(LOG_LEVEL_INFO, PSTR("SX1: No inverter registered")); return false; @@ -484,12 +634,10 @@ bool SolaxX1_cmd(void) { if (!strcasecmp(XdrvMailbox.data, "ReadIDinfo")) { solaxX1_global.Command_QueryID = true; - AddLog(LOG_LEVEL_INFO, PSTR("SX1: ReadIDinfo sent...")); return true; } else if (!strcasecmp(XdrvMailbox.data, "ReadConfig")) { #ifdef SOLAXX1_READCONFIG solaxX1_global.Command_QueryConfig = true; - AddLog(LOG_LEVEL_INFO, PSTR("SX1: ReadConfig sent...")); return true; #else AddLog(LOG_LEVEL_INFO, PSTR("SX1: Command not available. Please set compiler directive '#define SOLAXX1_READCONFIG'.")); @@ -501,8 +649,9 @@ bool SolaxX1_cmd(void) { } #ifdef USE_WEBSERVER -const char HTTP_SNS_solaxX1_Num[] PROGMEM = "{s}" D_SOLAX_X1 " %s{m}%s{m}{m} %s{e}"; -const char HTTP_SNS_solaxX1_Str[] PROGMEM = "{s}" D_SOLAX_X1 " %s{m}%s{e}"; +const char HTTP_SNS_solaxX1_Num[] PROGMEM = "{s}" D_SOLAX_X1 " %s{m}%s{m}{m}%s{e}"; +const char HTTP_SNS_solaxX1_Str[] PROGMEM = "{s}" D_SOLAX_X1 " %s%s{e}"; +const char HTTP_SNS_solaxX1_Mtr[] PROGMEM = "{s}" D_GATEWAY " %s{m}%s{m}{m}%s{e}"; #endif // USE_WEBSERVER void solaxX1_Show(uint32_t function) { @@ -523,7 +672,7 @@ void solaxX1_Show(uint32_t function) { dtostrfd(solaxX1.dc2_power, Settings->flag2.wattage_resolution, pv2_power); #endif char status[33]; - GetTextIndexed(status, sizeof(status), solaxX1.runMode + 1, kSolaxMode); + GetTextIndexed(status, sizeof(status), solaxX1.runMode + 2, kSolaxMode); switch (function) { case FUNC_JSON_APPEND: @@ -544,10 +693,23 @@ void solaxX1_Show(uint32_t function) { #ifdef USE_WEBSERVER case FUNC_WEB_COL_SENSOR: { String table_align = Settings->flag5.gui_table_align?"right":"left"; + if (solaxX1_global.MeterMode) { + char TempDataChar[33]; + WSContentSend_P(PSTR("
{e}")); + dtostrfd(solaxX1_global.MeterPower, Settings->flag2.wattage_resolution, TempDataChar); + WSContentSend_PD(HTTP_SNS_solaxX1_Mtr, D_POWERUSAGE, table_align.c_str(), TempDataChar, D_UNIT_WATT); + dtostrfd(solaxX1_global.MeterImport, Settings->flag2.energy_resolution, TempDataChar); + WSContentSend_PD(HTTP_SNS_solaxX1_Mtr, "Import", table_align.c_str(), TempDataChar, D_UNIT_KILOWATTHOUR); + dtostrfd(solaxX1_global.MeterExport, Settings->flag2.energy_resolution, TempDataChar); + WSContentSend_PD(HTTP_SNS_solaxX1_Mtr, "Export", table_align.c_str(), TempDataChar, D_UNIT_KILOWATTHOUR); + return; + } static uint32_t LastOnlineTime; if (solaxX1.runMode != -1) LastOnlineTime = TasmotaGlobal.uptime; if (TasmotaGlobal.uptime < LastOnlineTime + 300) { // Hide numeric live data, when inverter is offline for more than 5 min +#ifdef SOLAXX1_PV2 WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_SOLAR_POWER, table_align.c_str(), solar_power, D_UNIT_WATT); +#endif WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_PV1_VOLTAGE, table_align.c_str(), pv1_voltage, D_UNIT_VOLT); WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_PV1_CURRENT, table_align.c_str(), pv1_current, D_UNIT_AMPERE); WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_PV1_POWER, table_align.c_str(), pv1_power, D_UNIT_WATT); @@ -563,6 +725,7 @@ void solaxX1_Show(uint32_t function) { WSContentSend_P(HTTP_SNS_solaxX1_Num, D_UPTIME, table_align.c_str(), String(solaxX1.runtime_total).c_str(), D_UNIT_HOUR); break; } case FUNC_WEB_SENSOR: + if (solaxX1_global.MeterMode) return; char errorCodeString[33]; WSContentSend_P(HTTP_SNS_solaxX1_Str, D_STATUS, status); WSContentSend_P(HTTP_SNS_solaxX1_Str, D_ERROR, GetTextIndexed(errorCodeString, sizeof(errorCodeString), solaxX1_ParseErrorCode(solaxX1.errorCode), kSolaxError)); @@ -580,8 +743,11 @@ bool Xnrg12(uint32_t function) { bool result = false; switch (function) { + case FUNC_EVERY_100_MSECOND: + if (solaxX1_global.MeterMode) solaxX1_CyclicTask(); + break; case FUNC_EVERY_250_MSECOND: - solaxX1_250MSecond(); + if (!solaxX1_global.MeterMode) solaxX1_CyclicTask(); break; #ifdef USE_WEBSERVER case FUNC_WEB_COL_SENSOR: From 80686a8c52f40a48e838a2cebb73bc8220fa4c3c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:05:07 +0200 Subject: [PATCH 035/205] Update changelogs --- CHANGELOG.md | 4 ++++ RELEASENOTES.md | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9e67e918..a197bd880 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,16 @@ All notable changes to this project will be documented in this file. - DALI command `DaliTarget` to set light control broadcast, group number or gear number - Mitsubishi Electric HVAC Operation time for MiElHVAC (#22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC (#22345) +- Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC (#22347) +- SolaxX1 Meter mode (#22330) ### Breaking Changed ### Changed - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default +- ESP32 Framework (Arduino Core) from v3.1.0.241015 to v3.1.0.241023 (#22351) +- Shutter optimized behavior to publish shutter data with sensor request (#22353) ### Fixed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 325a6c26b..00547901d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -122,14 +122,17 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliTarget` to set light control broadcast, group number or gear number - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) +- Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) +- SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) ### Breaking Changed ### Changed -- ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 [#22299](https://github.com/arendst/Tasmota/issues/22299) +- ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241023 [#22351](https://github.com/arendst/Tasmota/issues/22351) - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default +- Shutter optimized behavior to publish shutter data with sensor request [#22353](https://github.com/arendst/Tasmota/issues/22353) - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed From 886221a1d659872ce6197111c0fa9ef77a7a23db Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 24 Oct 2024 23:03:14 +0200 Subject: [PATCH 036/205] Add experimental support for Shelly DALI Dimmer Gen3 (See template in file xdrv_75_dali.ino) --- CHANGELOG.md | 3 + RELEASENOTES.md | 2 + tasmota/include/tasmota_template.h | 14 ++-- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 80 ++++++++++++-------- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a197bd880..d2de0c685 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file. - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC (#22345) - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC (#22347) - SolaxX1 Meter mode (#22330) +- DALI inverted signal configuration using GPIO DALI RX_i/TX_i +- Experimental support for Shelly DALI Dimmer Gen3 (See template in file xdrv_75_dali.ino) ### Breaking Changed @@ -24,6 +26,7 @@ All notable changes to this project will be documented in this file. ### Fixed ### Removed +- DALI inverted signal configuration using compile time defines ## [14.3.0.1] 20241022 ### Added diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 00547901d..e22ff627e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -120,6 +120,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups - DALI command `DaliTarget` to set light control broadcast, group number or gear number +- DALI inverted signal configuration using GPIO DALI RX_i/TX_i +- Experimental support for Shelly DALI Dimmer Gen3 (See template in file xdrv_75_dali.ino) - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 053782636..053df5677 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -224,6 +224,7 @@ enum UserSelectablePins { GPIO_WOOLIIS_RX, // Wooliis Battery capacity monitor Serial RX GPIO_ADC_VOLTAGE, GPIO_ADC_CURRENT, // Analog Voltage and Current GPIO_BL0906_RX, // BL0906 Serial interface + GPIO_DALI_RX_INV, GPIO_DALI_TX_INV, // DALI GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage with max 2045 @@ -495,6 +496,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_WOOLIIS_RX "|" D_SENSOR_ADC_VOLTAGE "|" D_SENSOR_ADC_CURRENT "|" D_SENSOR_BL0906_RX "|" + D_SENSOR_DALI_RX "_i|" D_SENSOR_DALI_TX "_i|" ; const char kSensorNamesFixed[] PROGMEM = @@ -592,11 +594,6 @@ const uint16_t kGpioNiceList[] PROGMEM = { * Protocol specifics \*-------------------------------------------------------------------------------------------*/ -#ifdef USE_DALI - AGPIO(GPIO_DALI_RX), // DALI RX - AGPIO(GPIO_DALI_TX), // DALI TX -#endif // USE_DALI - #ifdef USE_I2C AGPIO(GPIO_I2C_SCL) + MAX_I2C, // I2C SCL AGPIO(GPIO_I2C_SDA) + MAX_I2C, // I2C SDA @@ -834,6 +831,13 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #endif // USE_LIGHT +#ifdef USE_DALI + AGPIO(GPIO_DALI_TX), // DALI TX + AGPIO(GPIO_DALI_TX_INV), // DALI TX inverted + AGPIO(GPIO_DALI_RX), // DALI RX + AGPIO(GPIO_DALI_RX_INV), // DALI RX inverted +#endif // USE_DALI + /*-------------------------------------------------------------------------------------------*\ * Transmission sensors \*-------------------------------------------------------------------------------------------*/ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index 3dbe46f8e..887e279ab 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -19,6 +19,9 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 1.0.0.1 20241024 update - Change from signal invert defines to GPIO config DALI RX_i/DALI TX_i + - Fix inverted DALI signal support + - Experimental support for Shelly DALI Dimmer Gen3 1.0.0.0 20241022 update - Refactor commission - Add receive collision detection 0.1.0.8 20241019 update - Rename command `DaliCommission` to `DaliScan` @@ -79,19 +82,16 @@ * 16 group address 100AAAAS * Special command 101CCCC1 to 110CCCC1 * A = Address bit, S = 0 Direct Arc Power control, S = 1 Command, C = Special command + * + * Shelly DALI Dimmer Gen3 (ESP32C3-8M) + * Template {"NAME":"Shelly DALI Dimmer Gen3","GPIO":[34,4736,1,3840,11360,11392,128,129,1,1,576,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1} + * AdcGpio1 10000,10000,4000 <- Temperature parameters + * Backlog ButtonTopic 0; SetOption1 1; SetOption11 0; SetOption32 20 + * rule1 on button1#state=2 do dimmer + endon on button2#state=2 do dimmer - endon on button1#state=3 do power 2 endon on button2#state=3 do power 2 endon \*********************************************************************************************/ #define XDRV_75 75 -#ifndef DALI_IN_INVERT -#define DALI_IN_INVERT 0 // DALI RX inverted (1) -#endif -#ifndef DALI_OUT_INVERT -#define DALI_OUT_INVERT 0 // DALI TX inverted (1) -#endif -#ifndef DALI_MAX_SHORT_ADDRESS -#define DALI_MAX_SHORT_ADDRESS 64 // DALI default max short addresses -#endif #ifndef DALI_INIT_STATE #define DALI_INIT_STATE 50 // DALI init dimmer state 50/254 #endif @@ -280,7 +280,7 @@ void (* const DALICommand[])(void) PROGMEM = { &CmndDaliSend, &CmndDaliQuery, &CmndDaliScan, &CmndDaliGroup, &CmndDaliGear }; struct DALI { - uint32_t bit_time; + uint32_t bit_cycles; uint32_t last_activity; uint32_t received_dali_data; // Data received from DALI bus uint8_t pin_rx; @@ -295,6 +295,8 @@ struct DALI { bool response; bool light_sync; bool probe; + bool invert_rx; + bool invert_tx; } *Dali = nullptr; /*********************************************************************************************\ @@ -334,7 +336,7 @@ uint32_t DaliAddress2Target(uint32_t adr) { void DaliEnableRxInterrupt(void) { Dali->available = false; - attachInterrupt(Dali->pin_rx, DaliReceiveData, FALLING); + attachInterrupt(Dali->pin_rx, DaliReceiveData, (Dali->invert_rx) ? RISING : FALLING); } void DaliDisableRxInterrupt(void) { @@ -365,16 +367,15 @@ void DaliReceiveData(void) { */ if (Dali->available) { return; } // Skip if last input is not yet handled uint32_t gap_time = millis() - Dali->last_activity; - uint32_t wait = ESP.getCycleCount() + (Dali->bit_time / 2); + uint32_t wait = ESP.getCycleCount() + (Dali->bit_cycles / 2); int bit_state = 0; bool dali_read; uint32_t received_dali_data = 0; uint32_t bit_number = 0; while (bit_number < 38) { while (ESP.getCycleCount() < wait); - wait += Dali->bit_time; // Auto roll-over - dali_read = digitalRead(Dali->pin_rx); - if (DALI_IN_INVERT) { dali_read != dali_read; } + wait += Dali->bit_cycles; // Auto roll-over + dali_read = (digitalRead(Dali->pin_rx) != Dali->invert_rx); #ifdef DALI_DEBUG digitalWrite(DALI_DEBUG_PIN, bit_number&1); // Add LogicAnalyzer poll indication #endif // DALI_DEBUG @@ -465,13 +466,12 @@ void DaliSendDataOnce(uint16_t send_dali_data) { } } - digitalWrite(Dali->pin_tx, (pin_value == DALI_OUT_INVERT) ? LOW : HIGH); - wait += Dali->bit_time; // Auto roll-over + digitalWrite(Dali->pin_tx, (Dali->invert_tx) ? !pin_value : pin_value); + wait += Dali->bit_cycles; // Auto roll-over while (ESP.getCycleCount() < wait); if (!collision) { - dali_read = digitalRead(Dali->pin_rx); - if (DALI_IN_INVERT) { dali_read != dali_read; } + dali_read = (digitalRead(Dali->pin_rx) != Dali->invert_rx); if ((HIGH == pin_value) && (LOW == dali_read)) { // Collision if write is 1 and bus is 0 collision = true; pin_value = LOW; @@ -686,7 +686,7 @@ void DaliProgramShortAddress(uint8_t shortadr) { // The slave shall store the received 6-bit address (AAAAAA) as a short address if it is selected. DaliSendData(DALI_PROGRAM_SHORT_ADDRESS, (shortadr << 1) | 0x01); - AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Set short address %d"), shortadr +1); + AddLog(LOG_LEVEL_INFO, PSTR("DLI: Set short address %d"), shortadr +1); } /*-------------------------------------------------------------------------------------------*/ @@ -738,9 +738,9 @@ uint32_t DaliCommission(uint8_t init_arg) { #ifdef USE_LIGHT DaliInitLight(); uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address(Dali->target) : DALI_BROADCAST_DP; - DaliSendData(address, Dali->dimmer); // Restore lights + DaliSendData(address, Dali->power); // Restore lights #else - DaliSendData(DALI_BROADCAST_DP, Dali->dimmer); // Restore lights + DaliSendData(DALI_BROADCAST_DP, Dali->power); // Restore lights #endif // USE_LIGHT return cnt; } @@ -763,6 +763,9 @@ void ResponseDali(void) { void DaliLoop(void) { if (!Dali->available || Dali->response) { return; } + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DLI: Rx 0x%05X"), Dali->received_dali_data); + if (Dali->received_dali_data &0x00010000) { Dali->available = false; return; // Rx collision @@ -842,28 +845,45 @@ bool DaliSetChannels(void) { /*-------------------------------------------------------------------------------------------*/ bool DaliInit(void) { - if (!PinUsed(GPIO_DALI_TX) || !PinUsed(GPIO_DALI_RX)) { return false; } - Dali = (DALI*)calloc(sizeof(DALI), 1); if (!Dali) { return false; } - Dali->pin_rx = Pin(GPIO_DALI_RX); - Dali->pin_tx = Pin(GPIO_DALI_TX); + Dali->pin_tx = -1; + if (PinUsed(GPIO_DALI_TX)) { + Dali->pin_tx = Pin(GPIO_DALI_TX); + } + else if (PinUsed(GPIO_DALI_TX_INV)) { + Dali->pin_tx = Pin(GPIO_DALI_TX_INV); + Dali->invert_tx = true; + } + Dali->pin_rx = -1; + if (PinUsed(GPIO_DALI_RX)) { + Dali->pin_rx = Pin(GPIO_DALI_RX); + } + else if (PinUsed(GPIO_DALI_RX_INV)) { + Dali->pin_rx = Pin(GPIO_DALI_RX_INV); + Dali->invert_rx = true; + } + if ((-1 == Dali->pin_tx) || (-1 == Dali->pin_rx)) { + free(Dali); + return false; + } - AddLog(LOG_LEVEL_INFO, PSTR("DLI: GPIO%d(RX) and GPIO%d(TX)"), Dali->pin_rx, Dali->pin_tx); + AddLog(LOG_LEVEL_INFO, PSTR("DLI: GPIO%d(RX%s) and GPIO%d(TX%s)"), + Dali->pin_rx, (Dali->invert_rx)?"i":"", Dali->pin_tx, (Dali->invert_tx)?"i":""); pinMode(Dali->pin_tx, OUTPUT); - digitalWrite(Dali->pin_tx, HIGH); + digitalWrite(Dali->pin_tx, (Dali->invert_tx) ? LOW : HIGH); // Idle pinMode(Dali->pin_rx, INPUT); #ifdef DALI_DEBUG pinMode(DALI_DEBUG_PIN, OUTPUT); digitalWrite(DALI_DEBUG_PIN, HIGH); #endif // DALI_DEBUG - Dali->max_short_address = (DALI_MAX_SHORT_ADDRESS <= 64) ? DALI_MAX_SHORT_ADDRESS : 64; + Dali->max_short_address = 64; Dali->dimmer = DALI_INIT_STATE; // Manchester twice 1200 bps = 2400 bps = 417 (protocol 416.76 +/- 10%) us - Dali->bit_time = ESP.getCpuFreqMHz() * 1000000 / 2400; + Dali->bit_cycles = ESP.getCpuFreqMHz() * 1000000 / 2400; DaliEnableRxInterrupt(); From 0fd16f8725af358ce4224d244e5df8cc9ebc59a5 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Fri, 25 Oct 2024 11:39:14 +0200 Subject: [PATCH 037/205] HASPmota `haspmota.get_pages()` to get the sorted list of pages (#22358) --- CHANGELOG.md | 1 + .../lv_haspmota/src/embedded/lv_haspmota.be | 6 + .../src/solidify/solidified_lv_haspmota.h | 2160 +++++++++-------- 3 files changed, 1101 insertions(+), 1066 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2de0c685..b83c987bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. - SolaxX1 Meter mode (#22330) - DALI inverted signal configuration using GPIO DALI RX_i/TX_i - Experimental support for Shelly DALI Dimmer Gen3 (See template in file xdrv_75_dali.ino) +- HASPmota `haspmota.get_pages()` to get the sorted list of pages ### Breaking Changed diff --git a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be index 31cf11e98..082110dcb 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be +++ b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be @@ -2679,6 +2679,12 @@ class HASPmota return self.lvh_pages[self.lvh_page_cur_idx] end #==================================================================== + # return an array of all pages numbers + #==================================================================== + def get_pages() + return self.pages_list_sorted(nil) + end + #==================================================================== # return the current page being parsed with JSONL as `lvh_page` object #==================================================================== def get_page_cur_parsing() diff --git a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h index 2e72d3e11..3936938da 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h +++ b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h @@ -10932,83 +10932,83 @@ be_local_class(lvh_page, be_str_weak(lvh_page) ); extern const bclass be_class_HASPmota; -// compact class 'HASPmota' ktab size: 124, total: 196 (saved 576 bytes) +// compact class 'HASPmota' ktab size: 124, total: 197 (saved 584 bytes) static const bvalue be_ktab_class_HASPmota[124] = { - /* K0 */ be_nested_str_weak(has), - /* K1 */ be_nested_str_weak(page), - /* K2 */ be_nested_str_weak(int), - /* K3 */ be_nested_str_weak(lvh_page_cur_idx_parsing), - /* K4 */ be_nested_str_weak(lvh_page_cur_idx), - /* K5 */ be_nested_str_weak(lvh_pages), - /* K6 */ be_nested_str_weak(contains), - /* K7 */ be_nested_str_weak(lvh_page), - /* K8 */ be_nested_str_weak(find), + /* K0 */ be_nested_str_weak(get_page_cur), + /* K1 */ be_nested_str_weak(pages_list_sorted), + /* K2 */ be_nested_str_weak(lvh_page_cur_idx), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_str_weak(prev), + /* K5 */ be_nested_str_weak(next), + /* K6 */ be_nested_str_weak(back), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(delete), /* K9 */ be_nested_str_weak(id), - /* K10 */ be_const_int(0), - /* K11 */ be_nested_str_weak(get_page_cur_parsing), - /* K12 */ be_nested_str_weak(prev), - /* K13 */ be_nested_str_weak(next), - /* K14 */ be_nested_str_weak(back), - /* K15 */ be_nested_str_weak(get_page_cur), - /* K16 */ be_nested_str_weak(pages_list_sorted), - /* K17 */ be_const_int(1), - /* K18 */ be_nested_str_weak(delete), - /* K19 */ be_nested_str_weak(re_page_target), - /* K20 */ be_nested_str_weak(match), - /* K21 */ be_nested_str_weak(show), - /* K22 */ be_nested_str_weak(global), - /* K23 */ be_nested_str_weak(introspect), - /* K24 */ be_nested_str_weak(obj), - /* K25 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20_X25s_X20for_X20_X27obj_X27_X3A_X20_X25s), - /* K26 */ be_nested_str_weak(get_obj), - /* K27 */ be_nested_str_weak(parentid), - /* K28 */ be_nested_str_weak(_lv_obj), - /* K29 */ be_nested_str_weak(get_scr), - /* K30 */ be_nested_str_weak(get), - /* K31 */ be_nested_str_weak(lvh_), - /* K32 */ be_nested_str_weak(class), - /* K33 */ be_nested_str_weak(lvh_obj), - /* K34 */ be_nested_str_weak(module), - /* K35 */ be_nested_str_weak(HSP_X3A_X20Cannot_X20find_X20object_X20of_X20type_X20_X25s), - /* K36 */ be_nested_str_weak(add_obj), - /* K37 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X3A_X27_X25s_X27_X20for_X20_X27id_X27_X3A0), - /* K38 */ be_nested_str_weak(keys), - /* K39 */ be_nested_str_weak(stop_iteration), - /* K40 */ be_nested_str_weak(post_config), - /* K41 */ be_nested_str_weak(berry_run), - /* K42 */ be_nested_str_weak(nil), - /* K43 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K44 */ be_nested_str_weak(function), - /* K45 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K46 */ be_nested_str_weak(page_show), - /* K47 */ be_nested_str_weak(remove), - /* K48 */ be_nested_str_weak(p_X25s), - /* K49 */ be_nested_str_weak(push), - /* K50 */ be_nested_str_weak(sort), - /* K51 */ be_nested_str_weak(toptr), - /* K52 */ be_nested_str_weak(event), - /* K53 */ be_nested_str_weak(_p), - /* K54 */ be_nested_str_weak(lv), - /* K55 */ be_nested_str_weak(lv_event), - /* K56 */ be_nested_str_weak(get_user_data), - /* K57 */ be_nested_str_weak(fromptr), - /* K58 */ be_nested_str_weak(instance), - /* K59 */ be_nested_str_weak(event_cb), - /* K60 */ be_const_class(be_class_HASPmota), - /* K61 */ be_nested_str_weak(version), - /* K62 */ be_nested_str_weak(cb), - /* K63 */ be_nested_str_weak(gen_cb), - /* K64 */ be_nested_str_weak(add_event_cb), - /* K65 */ be_nested_str_weak(json), - /* K66 */ be_nested_str_weak(load), - /* K67 */ be_nested_str_weak(parse_page), - /* K68 */ be_nested_str_weak(parse_obj), - /* K69 */ be_nested_str_weak(value_error), - /* K70 */ be_nested_str_weak(unable_X20to_X20parse_X20JSON_X20line), - /* K71 */ be_nested_str_weak(fix_lv_version), - /* K72 */ be_nested_str_weak(re), - /* K73 */ be_nested_str_weak(compile), - /* K74 */ be_nested_str_weak(p_X5Cd_X2B), + /* K10 */ be_nested_str_weak(re_page_target), + /* K11 */ be_nested_str_weak(match), + /* K12 */ be_nested_str_weak(lvh_pages), + /* K13 */ be_nested_str_weak(show), + /* K14 */ be_nested_str_weak(cb), + /* K15 */ be_nested_str_weak(introspect), + /* K16 */ be_nested_str_weak(event_cb), + /* K17 */ be_nested_str_weak(gen_cb), + /* K18 */ be_nested_str_weak(_lv_obj), + /* K19 */ be_nested_str_weak(add_event_cb), + /* K20 */ be_nested_str_weak(toptr), + /* K21 */ be_nested_str_weak(string), + /* K22 */ be_nested_str_weak(json), + /* K23 */ be_nested_str_weak(r), + /* K24 */ be_nested_str_weak(read), + /* K25 */ be_nested_str_weak(close), + /* K26 */ be_nested_str_weak(split), + /* K27 */ be_nested_str_weak(_X0A), + /* K28 */ be_nested_str_weak(load), + /* K29 */ be_nested_str_weak(instance), + /* K30 */ be_nested_str_weak(tasmota), + /* K31 */ be_nested_str_weak(loglevel), + /* K32 */ be_nested_str_weak(log), + /* K33 */ be_nested_str_weak(HSP_X3A_X20parsing_X20line_X20_X27_X25s_X27), + /* K34 */ be_nested_str_weak(parse_page), + /* K35 */ be_nested_str_weak(value_error), + /* K36 */ be_nested_str_weak(no_X20page_X20_X27id_X27_X20defined), + /* K37 */ be_nested_str_weak(parse_obj), + /* K38 */ be_nested_str_weak(lvh_page_cur_idx_parsing), + /* K39 */ be_nested_str_weak(tr), + /* K40 */ be_nested_str_weak(_X20_X09), + /* K41 */ be_nested_str_weak(), + /* K42 */ be_nested_str_weak(HSP_X3A_X20invalid_X20JSON_X20line_X20_X27_X25s_X27), + /* K43 */ be_const_int(2), + /* K44 */ be_nested_str_weak(remove), + /* K45 */ be_nested_str_weak(no_X20page_X20object_X20defined), + /* K46 */ be_nested_str_weak(event), + /* K47 */ be_nested_str_weak(_p), + /* K48 */ be_nested_str_weak(lv), + /* K49 */ be_nested_str_weak(lv_event), + /* K50 */ be_nested_str_weak(get_user_data), + /* K51 */ be_nested_str_weak(fromptr), + /* K52 */ be_const_class(be_class_HASPmota), + /* K53 */ be_nested_str_weak(get), + /* K54 */ be_nested_str_weak(version), + /* K55 */ be_nested_str_weak(int), + /* K56 */ be_nested_str_weak(fix_lv_version), + /* K57 */ be_nested_str_weak(re), + /* K58 */ be_nested_str_weak(compile), + /* K59 */ be_nested_str_weak(p_X5Cd_X2B), + /* K60 */ be_nested_str_weak(keys), + /* K61 */ be_nested_str_weak(push), + /* K62 */ be_nested_str_weak(stop_iteration), + /* K63 */ be_nested_str_weak(sort), + /* K64 */ be_nested_str_weak(find), + /* K65 */ be_nested_str_weak(page_show), + /* K66 */ be_nested_str_weak(contains), + /* K67 */ be_nested_str_weak(global), + /* K68 */ be_nested_str_weak(p_X25s), + /* K69 */ be_nested_str_weak(EVENT_CLICKED), + /* K70 */ be_nested_str_weak(_action), + /* K71 */ be_nested_str_weak(has), + /* K72 */ be_nested_str_weak(page), + /* K73 */ be_nested_str_weak(lvh_page), + /* K74 */ be_nested_str_weak(get_page_cur_parsing), /* K75 */ be_nested_str_weak(path), /* K76 */ be_nested_str_weak(def_templ_name), /* K77 */ be_nested_str_weak(exists), @@ -11039,112 +11039,30 @@ static const bvalue be_ktab_class_HASPmota[124] = { /* K102 */ be_nested_str_weak(layer_top), /* K103 */ be_nested_str_weak(set_style_bg_opa), /* K104 */ be_nested_str_weak(_load), - /* K105 */ be_const_int(2), - /* K106 */ be_nested_str_weak(EVENT_CLICKED), - /* K107 */ be_nested_str_weak(_action), - /* K108 */ be_nested_str_weak(string), - /* K109 */ be_nested_str_weak(r), - /* K110 */ be_nested_str_weak(read), - /* K111 */ be_nested_str_weak(close), - /* K112 */ be_nested_str_weak(split), - /* K113 */ be_nested_str_weak(_X0A), - /* K114 */ be_nested_str_weak(tasmota), - /* K115 */ be_nested_str_weak(loglevel), - /* K116 */ be_nested_str_weak(log), - /* K117 */ be_nested_str_weak(HSP_X3A_X20parsing_X20line_X20_X27_X25s_X27), - /* K118 */ be_nested_str_weak(no_X20page_X20_X27id_X27_X20defined), - /* K119 */ be_nested_str_weak(tr), - /* K120 */ be_nested_str_weak(_X20_X09), - /* K121 */ be_nested_str_weak(), - /* K122 */ be_nested_str_weak(HSP_X3A_X20invalid_X20JSON_X20line_X20_X27_X25s_X27), - /* K123 */ be_nested_str_weak(no_X20page_X20object_X20defined), + /* K105 */ be_nested_str_weak(obj), + /* K106 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20_X25s_X20for_X20_X27obj_X27_X3A_X20_X25s), + /* K107 */ be_nested_str_weak(get_obj), + /* K108 */ be_nested_str_weak(parentid), + /* K109 */ be_nested_str_weak(get_scr), + /* K110 */ be_nested_str_weak(lvh_), + /* K111 */ be_nested_str_weak(class), + /* K112 */ be_nested_str_weak(lvh_obj), + /* K113 */ be_nested_str_weak(module), + /* K114 */ be_nested_str_weak(HSP_X3A_X20Cannot_X20find_X20object_X20of_X20type_X20_X25s), + /* K115 */ be_nested_str_weak(add_obj), + /* K116 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X3A_X27_X25s_X27_X20for_X20_X27id_X27_X3A0), + /* K117 */ be_nested_str_weak(post_config), + /* K118 */ be_nested_str_weak(berry_run), + /* K119 */ be_nested_str_weak(nil), + /* K120 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K121 */ be_nested_str_weak(function), + /* K122 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K123 */ be_nested_str_weak(unable_X20to_X20parse_X20JSON_X20line), }; extern const bclass be_class_HASPmota; -/******************************************************************** -** Solidified function: parse_page -********************************************************************/ -be_local_closure(class_HASPmota_parse_page, /* name */ - be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(parse_page), - &be_const_str_solidified, - ( &(const binstruction[59]) { /* code */ - 0x8C080300, // 0000 GETMET R2 R1 K0 - 0x58100001, // 0001 LDCONST R4 K1 - 0x7C080400, // 0002 CALL R2 2 - 0x780A0035, // 0003 JMPF R2 #003A - 0x60080004, // 0004 GETGBL R2 G4 - 0x940C0301, // 0005 GETIDX R3 R1 K1 - 0x7C080200, // 0006 CALL R2 1 - 0x1C080502, // 0007 EQ R2 R2 K2 - 0x780A0030, // 0008 JMPF R2 #003A - 0x60080009, // 0009 GETGBL R2 G9 - 0x940C0301, // 000A GETIDX R3 R1 K1 - 0x7C080200, // 000B CALL R2 1 - 0x90020602, // 000C SETMBR R0 K3 R2 - 0x880C0104, // 000D GETMBR R3 R0 K4 - 0x4C100000, // 000E LDNIL R4 - 0x1C0C0604, // 000F EQ R3 R3 R4 - 0x780E0000, // 0010 JMPF R3 #0012 - 0x90020802, // 0011 SETMBR R0 K4 R2 - 0x880C0105, // 0012 GETMBR R3 R0 K5 - 0x8C0C0706, // 0013 GETMET R3 R3 K6 - 0x5C140400, // 0014 MOVE R5 R2 - 0x7C0C0400, // 0015 CALL R3 2 - 0x740E0006, // 0016 JMPT R3 #001E - 0x880C0107, // 0017 GETMBR R3 R0 K7 - 0x88100105, // 0018 GETMBR R4 R0 K5 - 0x5C140600, // 0019 MOVE R5 R3 - 0x5C180400, // 001A MOVE R6 R2 - 0x5C1C0000, // 001B MOVE R7 R0 - 0x7C140400, // 001C CALL R5 2 - 0x98100405, // 001D SETIDX R4 R2 R5 - 0x8C0C0308, // 001E GETMET R3 R1 K8 - 0x58140009, // 001F LDCONST R5 K9 - 0x7C0C0400, // 0020 CALL R3 2 - 0x1C0C070A, // 0021 EQ R3 R3 K10 - 0x780E0016, // 0022 JMPF R3 #003A - 0x8C0C010B, // 0023 GETMET R3 R0 K11 - 0x7C0C0200, // 0024 CALL R3 1 - 0x60100009, // 0025 GETGBL R4 G9 - 0x8C140308, // 0026 GETMET R5 R1 K8 - 0x581C000C, // 0027 LDCONST R7 K12 - 0x4C200000, // 0028 LDNIL R8 - 0x7C140600, // 0029 CALL R5 3 - 0x7C100200, // 002A CALL R4 1 - 0x900E1804, // 002B SETMBR R3 K12 R4 - 0x60100009, // 002C GETGBL R4 G9 - 0x8C140308, // 002D GETMET R5 R1 K8 - 0x581C000D, // 002E LDCONST R7 K13 - 0x4C200000, // 002F LDNIL R8 - 0x7C140600, // 0030 CALL R5 3 - 0x7C100200, // 0031 CALL R4 1 - 0x900E1A04, // 0032 SETMBR R3 K13 R4 - 0x60100009, // 0033 GETGBL R4 G9 - 0x8C140308, // 0034 GETMET R5 R1 K8 - 0x581C000E, // 0035 LDCONST R7 K14 - 0x4C200000, // 0036 LDNIL R8 - 0x7C140600, // 0037 CALL R5 3 - 0x7C100200, // 0038 CALL R4 1 - 0x900E1C04, // 0039 SETMBR R3 K14 R4 - 0x80000000, // 003A RET 0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: page_show ********************************************************************/ @@ -11195,23 +11113,23 @@ be_local_closure(class_HASPmota_page_show, /* name */ ( &(const binstruction[108]) { /* code */ 0x84100000, // 0000 CLOSURE R4 P0 0x4C140000, // 0001 LDNIL R5 - 0x8C18010F, // 0002 GETMET R6 R0 K15 + 0x8C180100, // 0002 GETMET R6 R0 K0 0x7C180200, // 0003 CALL R6 1 - 0x8C1C0110, // 0004 GETMET R7 R0 K16 - 0x88240104, // 0005 GETMBR R9 R0 K4 + 0x8C1C0101, // 0004 GETMET R7 R0 K1 + 0x88240102, // 0005 GETMBR R9 R0 K2 0x7C1C0400, // 0006 CALL R7 2 0x6020000C, // 0007 GETGBL R8 G12 0x5C240E00, // 0008 MOVE R9 R7 0x7C200200, // 0009 CALL R8 1 - 0x18201111, // 000A LE R8 R8 K17 + 0x18201103, // 000A LE R8 R8 K3 0x78220001, // 000B JMPF R8 #000E 0x4C200000, // 000C LDNIL R8 0x80041000, // 000D RET 1 R8 - 0x1C20030C, // 000E EQ R8 R1 K12 + 0x1C200304, // 000E EQ R8 R1 K4 0x78220009, // 000F JMPF R8 #001A 0x5C200800, // 0010 MOVE R8 R4 0x60240009, // 0011 GETGBL R9 G9 - 0x88280D0C, // 0012 GETMBR R10 R6 K12 + 0x88280D04, // 0012 GETMBR R10 R6 K4 0x7C240200, // 0013 CALL R9 1 0x5429FFFE, // 0014 LDINT R10 -1 0x94280E0A, // 0015 GETIDX R10 R7 R10 @@ -11219,41 +11137,41 @@ be_local_closure(class_HASPmota_page_show, /* name */ 0x7C200600, // 0017 CALL R8 3 0x5C141000, // 0018 MOVE R5 R8 0x70020041, // 0019 JMP #005C - 0x1C20030D, // 001A EQ R8 R1 K13 + 0x1C200305, // 001A EQ R8 R1 K5 0x78220008, // 001B JMPF R8 #0025 0x5C200800, // 001C MOVE R8 R4 0x60240009, // 001D GETGBL R9 G9 - 0x88280D0D, // 001E GETMBR R10 R6 K13 + 0x88280D05, // 001E GETMBR R10 R6 K5 0x7C240200, // 001F CALL R9 1 - 0x94280F11, // 0020 GETIDX R10 R7 K17 + 0x94280F03, // 0020 GETIDX R10 R7 K3 0x5C2C0E00, // 0021 MOVE R11 R7 0x7C200600, // 0022 CALL R8 3 0x5C141000, // 0023 MOVE R5 R8 0x70020036, // 0024 JMP #005C - 0x1C20030E, // 0025 EQ R8 R1 K14 + 0x1C200306, // 0025 EQ R8 R1 K6 0x7822000B, // 0026 JMPF R8 #0033 0x5C200800, // 0027 MOVE R8 R4 0x60240009, // 0028 GETGBL R9 G9 - 0x88280D0E, // 0029 GETMBR R10 R6 K14 + 0x88280D06, // 0029 GETMBR R10 R6 K6 0x7C240200, // 002A CALL R9 1 - 0x8C280110, // 002B GETMET R10 R0 K16 + 0x8C280101, // 002B GETMET R10 R0 K1 0x4C300000, // 002C LDNIL R12 0x7C280400, // 002D CALL R10 2 - 0x9428150A, // 002E GETIDX R10 R10 K10 + 0x94281507, // 002E GETIDX R10 R10 K7 0x5C2C0E00, // 002F MOVE R11 R7 0x7C200600, // 0030 CALL R8 3 0x5C141000, // 0031 MOVE R5 R8 0x70020028, // 0032 JMP #005C - 0x1C200312, // 0033 EQ R8 R1 K18 + 0x1C200308, // 0033 EQ R8 R1 K8 0x78220017, // 0034 JMPF R8 #004D 0x5C200800, // 0035 MOVE R8 R4 0x60240009, // 0036 GETGBL R9 G9 - 0x88280D0E, // 0037 GETMBR R10 R6 K14 + 0x88280D06, // 0037 GETMBR R10 R6 K6 0x7C240200, // 0038 CALL R9 1 - 0x8C280110, // 0039 GETMET R10 R0 K16 + 0x8C280101, // 0039 GETMET R10 R0 K1 0x4C300000, // 003A LDNIL R12 0x7C280400, // 003B CALL R10 2 - 0x9428150A, // 003C GETIDX R10 R10 K10 + 0x94281507, // 003C GETIDX R10 R10 K7 0x5C2C0E00, // 003D MOVE R11 R7 0x7C200600, // 003E CALL R8 3 0x5C141000, // 003F MOVE R5 R8 @@ -11263,22 +11181,22 @@ be_local_closure(class_HASPmota_page_show, /* name */ 0x78220007, // 0043 JMPF R8 #004C 0x5C200800, // 0044 MOVE R8 R4 0x60240009, // 0045 GETGBL R9 G9 - 0x88280D0D, // 0046 GETMBR R10 R6 K13 + 0x88280D05, // 0046 GETMBR R10 R6 K5 0x7C240200, // 0047 CALL R9 1 - 0x94280F11, // 0048 GETIDX R10 R7 K17 + 0x94280F03, // 0048 GETIDX R10 R7 K3 0x5C2C0E00, // 0049 MOVE R11 R7 0x7C200600, // 004A CALL R8 3 0x5C141000, // 004B MOVE R5 R8 0x7002000E, // 004C JMP #005C - 0x88200113, // 004D GETMBR R8 R0 K19 - 0x8C201114, // 004E GETMET R8 R8 K20 + 0x8820010A, // 004D GETMBR R8 R0 K10 + 0x8C20110B, // 004E GETMET R8 R8 K11 0x5C280200, // 004F MOVE R10 R1 0x7C200400, // 0050 CALL R8 2 0x78220009, // 0051 JMPF R8 #005C 0x5C200800, // 0052 MOVE R8 R4 0x60240009, // 0053 GETGBL R9 G9 0x5429FFFE, // 0054 LDINT R10 -1 - 0x402A220A, // 0055 CONNECT R10 K17 R10 + 0x402A060A, // 0055 CONNECT R10 K3 R10 0x9428020A, // 0056 GETIDX R10 R1 R10 0x7C240200, // 0057 CALL R9 1 0x4C280000, // 0058 LDNIL R10 @@ -11288,14 +11206,14 @@ be_local_closure(class_HASPmota_page_show, /* name */ 0x4C200000, // 005C LDNIL R8 0x20200A08, // 005D NE R8 R5 R8 0x7822000B, // 005E JMPF R8 #006B - 0x24200B0A, // 005F GT R8 R5 K10 + 0x24200B07, // 005F GT R8 R5 K7 0x78220009, // 0060 JMPF R8 #006B - 0x88200105, // 0061 GETMBR R8 R0 K5 + 0x8820010C, // 0061 GETMBR R8 R0 K12 0x94201005, // 0062 GETIDX R8 R8 R5 0x4C240000, // 0063 LDNIL R9 0x20241009, // 0064 NE R9 R8 R9 0x78260003, // 0065 JMPF R9 #006A - 0x8C241115, // 0066 GETMET R9 R8 K21 + 0x8C24110D, // 0066 GETMET R9 R8 K13 0x5C2C0400, // 0067 MOVE R11 R2 0x5C300600, // 0068 MOVE R12 R3 0x7C240600, // 0069 CALL R9 3 @@ -11307,547 +11225,6 @@ be_local_closure(class_HASPmota_page_show, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: parse_obj -********************************************************************/ -be_local_closure(class_HASPmota_parse_obj, /* name */ - be_nested_proto( - 20, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(parse_obj), - &be_const_str_solidified, - ( &(const binstruction[239]) { /* code */ - 0xA40E2C00, // 0000 IMPORT R3 K22 - 0xA4122E00, // 0001 IMPORT R4 K23 - 0x60140009, // 0002 GETGBL R5 G9 - 0x8C180308, // 0003 GETMET R6 R1 K8 - 0x58200009, // 0004 LDCONST R8 K9 - 0x7C180400, // 0005 CALL R6 2 - 0x7C140200, // 0006 CALL R5 1 - 0x8C180308, // 0007 GETMET R6 R1 K8 - 0x58200018, // 0008 LDCONST R8 K24 - 0x7C180400, // 0009 CALL R6 2 - 0x4C1C0000, // 000A LDNIL R7 - 0x201C0C07, // 000B NE R7 R6 R7 - 0x781E0003, // 000C JMPF R7 #0011 - 0x601C0008, // 000D GETGBL R7 G8 - 0x5C200C00, // 000E MOVE R8 R6 - 0x7C1C0200, // 000F CALL R7 1 - 0x70020000, // 0010 JMP #0012 - 0x4C1C0000, // 0011 LDNIL R7 - 0x5C180E00, // 0012 MOVE R6 R7 - 0x8C1C010B, // 0013 GETMET R7 R0 K11 - 0x7C1C0200, // 0014 CALL R7 1 - 0x4C200000, // 0015 LDNIL R8 - 0x20200A08, // 0016 NE R8 R5 R8 - 0x78220011, // 0017 JMPF R8 #002A - 0x14200B0A, // 0018 LT R8 R5 K10 - 0x74220002, // 0019 JMPT R8 #001D - 0x542200FD, // 001A LDINT R8 254 - 0x24200A08, // 001B GT R8 R5 R8 - 0x7822000C, // 001C JMPF R8 #002A - 0x20200B0A, // 001D NE R8 R5 K10 - 0x74220002, // 001E JMPT R8 #0022 - 0x4C200000, // 001F LDNIL R8 - 0x1C200C08, // 0020 EQ R8 R6 R8 - 0x78220007, // 0021 JMPF R8 #002A - 0x60200001, // 0022 GETGBL R8 G1 - 0x60240018, // 0023 GETGBL R9 G24 - 0x58280019, // 0024 LDCONST R10 K25 - 0x5C2C0A00, // 0025 MOVE R11 R5 - 0x5C300C00, // 0026 MOVE R12 R6 - 0x7C240600, // 0027 CALL R9 3 - 0x7C200200, // 0028 CALL R8 1 - 0x80001000, // 0029 RET 0 - 0x8C200F1A, // 002A GETMET R8 R7 K26 - 0x5C280A00, // 002B MOVE R10 R5 - 0x7C200400, // 002C CALL R8 2 - 0x4C240000, // 002D LDNIL R9 - 0x20240C09, // 002E NE R9 R6 R9 - 0x7826005F, // 002F JMPF R9 #0090 - 0x4C240000, // 0030 LDNIL R9 - 0x20240A09, // 0031 NE R9 R5 R9 - 0x7826005C, // 0032 JMPF R9 #0090 - 0x4C240000, // 0033 LDNIL R9 - 0x1C241009, // 0034 EQ R9 R8 R9 - 0x78260059, // 0035 JMPF R9 #0090 - 0x60240009, // 0036 GETGBL R9 G9 - 0x8C280308, // 0037 GETMET R10 R1 K8 - 0x5830001B, // 0038 LDCONST R12 K27 - 0x7C280400, // 0039 CALL R10 2 - 0x7C240200, // 003A CALL R9 1 - 0x4C280000, // 003B LDNIL R10 - 0x4C2C0000, // 003C LDNIL R11 - 0x4C300000, // 003D LDNIL R12 - 0x2030120C, // 003E NE R12 R9 R12 - 0x78320007, // 003F JMPF R12 #0048 - 0x8C300F1A, // 0040 GETMET R12 R7 K26 - 0x5C381200, // 0041 MOVE R14 R9 - 0x7C300400, // 0042 CALL R12 2 - 0x5C281800, // 0043 MOVE R10 R12 - 0x4C300000, // 0044 LDNIL R12 - 0x2030140C, // 0045 NE R12 R10 R12 - 0x78320000, // 0046 JMPF R12 #0048 - 0x882C151C, // 0047 GETMBR R11 R10 K28 - 0x4C300000, // 0048 LDNIL R12 - 0x1C30160C, // 0049 EQ R12 R11 R12 - 0x78320002, // 004A JMPF R12 #004E - 0x8C300F1D, // 004B GETMET R12 R7 K29 - 0x7C300200, // 004C CALL R12 1 - 0x5C2C1800, // 004D MOVE R11 R12 - 0x8C30091E, // 004E GETMET R12 R4 K30 - 0x5C380000, // 004F MOVE R14 R0 - 0x003E3E06, // 0050 ADD R15 K31 R6 - 0x7C300600, // 0051 CALL R12 3 - 0x4C340000, // 0052 LDNIL R13 - 0x4C380000, // 0053 LDNIL R14 - 0x1C38180E, // 0054 EQ R14 R12 R14 - 0x783A0010, // 0055 JMPF R14 #0067 - 0x8C38091E, // 0056 GETMET R14 R4 K30 - 0x5C400600, // 0057 MOVE R16 R3 - 0x5C440C00, // 0058 MOVE R17 R6 - 0x7C380600, // 0059 CALL R14 3 - 0x4C3C0000, // 005A LDNIL R15 - 0x203C1C0F, // 005B NE R15 R14 R15 - 0x783E0009, // 005C JMPF R15 #0067 - 0x603C0004, // 005D GETGBL R15 G4 - 0x5C401C00, // 005E MOVE R16 R14 - 0x7C3C0200, // 005F CALL R15 1 - 0x1C3C1F20, // 0060 EQ R15 R15 K32 - 0x783E0004, // 0061 JMPF R15 #0067 - 0x5C3C1C00, // 0062 MOVE R15 R14 - 0x5C401600, // 0063 MOVE R16 R11 - 0x7C3C0200, // 0064 CALL R15 1 - 0x5C341E00, // 0065 MOVE R13 R15 - 0x88300121, // 0066 GETMBR R12 R0 K33 - 0x4C380000, // 0067 LDNIL R14 - 0x1C38180E, // 0068 EQ R14 R12 R14 - 0x783A000F, // 0069 JMPF R14 #007A - 0x8C380922, // 006A GETMET R14 R4 K34 - 0x5C400C00, // 006B MOVE R16 R6 - 0x7C380400, // 006C CALL R14 2 - 0x4C3C0000, // 006D LDNIL R15 - 0x203C1C0F, // 006E NE R15 R14 R15 - 0x783E0009, // 006F JMPF R15 #007A - 0x603C0004, // 0070 GETGBL R15 G4 - 0x5C401C00, // 0071 MOVE R16 R14 - 0x7C3C0200, // 0072 CALL R15 1 - 0x1C3C1F20, // 0073 EQ R15 R15 K32 - 0x783E0004, // 0074 JMPF R15 #007A - 0x5C3C1C00, // 0075 MOVE R15 R14 - 0x5C401600, // 0076 MOVE R16 R11 - 0x7C3C0200, // 0077 CALL R15 1 - 0x5C341E00, // 0078 MOVE R13 R15 - 0x88300121, // 0079 GETMBR R12 R0 K33 - 0x4C380000, // 007A LDNIL R14 - 0x1C38180E, // 007B EQ R14 R12 R14 - 0x783A0006, // 007C JMPF R14 #0084 - 0x60380001, // 007D GETGBL R14 G1 - 0x603C0018, // 007E GETGBL R15 G24 - 0x58400023, // 007F LDCONST R16 K35 - 0x5C440C00, // 0080 MOVE R17 R6 - 0x7C3C0400, // 0081 CALL R15 2 - 0x7C380200, // 0082 CALL R14 1 - 0x80001C00, // 0083 RET 0 - 0x5C381800, // 0084 MOVE R14 R12 - 0x5C3C1600, // 0085 MOVE R15 R11 - 0x5C400400, // 0086 MOVE R16 R2 - 0x5C440200, // 0087 MOVE R17 R1 - 0x5C481A00, // 0088 MOVE R18 R13 - 0x5C4C1400, // 0089 MOVE R19 R10 - 0x7C380A00, // 008A CALL R14 5 - 0x5C201C00, // 008B MOVE R8 R14 - 0x8C380F24, // 008C GETMET R14 R7 K36 - 0x5C400A00, // 008D MOVE R16 R5 - 0x5C441000, // 008E MOVE R17 R8 - 0x7C380600, // 008F CALL R14 3 - 0x1C240B0A, // 0090 EQ R9 R5 K10 - 0x7826000F, // 0091 JMPF R9 #00A2 - 0x4C240000, // 0092 LDNIL R9 - 0x20240C09, // 0093 NE R9 R6 R9 - 0x78260006, // 0094 JMPF R9 #009C - 0x60240001, // 0095 GETGBL R9 G1 - 0x60280018, // 0096 GETGBL R10 G24 - 0x582C0025, // 0097 LDCONST R11 K37 - 0x5C300C00, // 0098 MOVE R12 R6 - 0x7C280400, // 0099 CALL R10 2 - 0x7C240200, // 009A CALL R9 1 - 0x80001200, // 009B RET 0 - 0x8C24010B, // 009C GETMET R9 R0 K11 - 0x7C240200, // 009D CALL R9 1 - 0x8C24131A, // 009E GETMET R9 R9 K26 - 0x582C000A, // 009F LDCONST R11 K10 - 0x7C240400, // 00A0 CALL R9 2 - 0x5C201200, // 00A1 MOVE R8 R9 - 0x4C240000, // 00A2 LDNIL R9 - 0x20241009, // 00A3 NE R9 R8 R9 - 0x7826000C, // 00A4 JMPF R9 #00B2 - 0x60240010, // 00A5 GETGBL R9 G16 - 0x8C280326, // 00A6 GETMET R10 R1 K38 - 0x7C280200, // 00A7 CALL R10 1 - 0x7C240200, // 00A8 CALL R9 1 - 0xA8020004, // 00A9 EXBLK 0 #00AF - 0x5C281200, // 00AA MOVE R10 R9 - 0x7C280000, // 00AB CALL R10 0 - 0x942C020A, // 00AC GETIDX R11 R1 R10 - 0x9020140B, // 00AD SETMBR R8 R10 R11 - 0x7001FFFA, // 00AE JMP #00AA - 0x58240027, // 00AF LDCONST R9 K39 - 0xAC240200, // 00B0 CATCH R9 1 0 - 0xB0080000, // 00B1 RAISE 2 R0 R0 - 0x4C240000, // 00B2 LDNIL R9 - 0x20241009, // 00B3 NE R9 R8 R9 - 0x78260001, // 00B4 JMPF R9 #00B7 - 0x8C241128, // 00B5 GETMET R9 R8 K40 - 0x7C240200, // 00B6 CALL R9 1 - 0x4C240000, // 00B7 LDNIL R9 - 0x60280008, // 00B8 GETGBL R10 G8 - 0x8C2C0308, // 00B9 GETMET R11 R1 K8 - 0x58340029, // 00BA LDCONST R13 K41 - 0x7C2C0400, // 00BB CALL R11 2 - 0x7C280200, // 00BC CALL R10 1 - 0x202C152A, // 00BD NE R11 R10 K42 - 0x782E0012, // 00BE JMPF R11 #00D2 - 0xA8020005, // 00BF EXBLK 0 #00C6 - 0x602C000D, // 00C0 GETGBL R11 G13 - 0x5C301400, // 00C1 MOVE R12 R10 - 0x7C2C0200, // 00C2 CALL R11 1 - 0x5C241600, // 00C3 MOVE R9 R11 - 0xA8040001, // 00C4 EXBLK 1 1 - 0x7002000B, // 00C5 JMP #00D2 - 0xAC2C0002, // 00C6 CATCH R11 0 2 - 0x70020008, // 00C7 JMP #00D1 - 0x60340001, // 00C8 GETGBL R13 G1 - 0x60380018, // 00C9 GETGBL R14 G24 - 0x583C002B, // 00CA LDCONST R15 K43 - 0x5C401400, // 00CB MOVE R16 R10 - 0x5C441600, // 00CC MOVE R17 R11 - 0x5C481800, // 00CD MOVE R18 R12 - 0x7C380800, // 00CE CALL R14 4 - 0x7C340200, // 00CF CALL R13 1 - 0x70020000, // 00D0 JMP #00D2 - 0xB0080000, // 00D1 RAISE 2 R0 R0 - 0x4C2C0000, // 00D2 LDNIL R11 - 0x202C120B, // 00D3 NE R11 R9 R11 - 0x782E0018, // 00D4 JMPF R11 #00EE - 0xA802000B, // 00D5 EXBLK 0 #00E2 - 0x5C2C1200, // 00D6 MOVE R11 R9 - 0x7C2C0000, // 00D7 CALL R11 0 - 0x60300004, // 00D8 GETGBL R12 G4 - 0x5C341600, // 00D9 MOVE R13 R11 - 0x7C300200, // 00DA CALL R12 1 - 0x1C30192C, // 00DB EQ R12 R12 K44 - 0x78320002, // 00DC JMPF R12 #00E0 - 0x5C301600, // 00DD MOVE R12 R11 - 0x5C341000, // 00DE MOVE R13 R8 - 0x7C300200, // 00DF CALL R12 1 - 0xA8040001, // 00E0 EXBLK 1 1 - 0x7002000B, // 00E1 JMP #00EE - 0xAC2C0002, // 00E2 CATCH R11 0 2 - 0x70020008, // 00E3 JMP #00ED - 0x60340001, // 00E4 GETGBL R13 G1 - 0x60380018, // 00E5 GETGBL R14 G24 - 0x583C002D, // 00E6 LDCONST R15 K45 - 0x5C401400, // 00E7 MOVE R16 R10 - 0x5C441600, // 00E8 MOVE R17 R11 - 0x5C481800, // 00E9 MOVE R18 R12 - 0x7C380800, // 00EA CALL R14 4 - 0x7C340200, // 00EB CALL R13 1 - 0x70020000, // 00EC JMP #00EE - 0xB0080000, // 00ED RAISE 2 R0 R0 - 0x80000000, // 00EE RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: _remove_page -********************************************************************/ -be_local_closure(class_HASPmota__remove_page, /* name */ - be_nested_proto( - 8, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(_remove_page), - &be_const_str_solidified, - ( &(const binstruction[37]) { /* code */ - 0x8C08010F, // 0000 GETMET R2 R0 K15 - 0x7C080200, // 0001 CALL R2 1 - 0x8C080509, // 0002 GETMET R2 R2 K9 - 0x7C080200, // 0003 CALL R2 1 - 0x1C0C0202, // 0004 EQ R3 R1 R2 - 0x780E0008, // 0005 JMPF R3 #000F - 0x8C0C012E, // 0006 GETMET R3 R0 K46 - 0x58140012, // 0007 LDCONST R5 K18 - 0x5818000A, // 0008 LDCONST R6 K10 - 0x581C000A, // 0009 LDCONST R7 K10 - 0x7C0C0800, // 000A CALL R3 4 - 0x4C100000, // 000B LDNIL R4 - 0x1C100604, // 000C EQ R4 R3 R4 - 0x78120000, // 000D JMPF R4 #000F - 0x80000800, // 000E RET 0 - 0x880C0103, // 000F GETMBR R3 R0 K3 - 0x1C0C0601, // 0010 EQ R3 R3 R1 - 0x780E0001, // 0011 JMPF R3 #0014 - 0x880C0104, // 0012 GETMBR R3 R0 K4 - 0x90020603, // 0013 SETMBR R0 K3 R3 - 0x880C0105, // 0014 GETMBR R3 R0 K5 - 0x8C0C0706, // 0015 GETMET R3 R3 K6 - 0x5C140200, // 0016 MOVE R5 R1 - 0x7C0C0400, // 0017 CALL R3 2 - 0x780E0003, // 0018 JMPF R3 #001D - 0x880C0105, // 0019 GETMBR R3 R0 K5 - 0x8C0C072F, // 001A GETMET R3 R3 K47 - 0x5C140200, // 001B MOVE R5 R1 - 0x7C0C0400, // 001C CALL R3 2 - 0x600C0018, // 001D GETGBL R3 G24 - 0x58100030, // 001E LDCONST R4 K48 - 0x5C140200, // 001F MOVE R5 R1 - 0x7C0C0400, // 0020 CALL R3 2 - 0xB8122C00, // 0021 GETNGBL R4 K22 - 0x4C140000, // 0022 LDNIL R5 - 0x90100605, // 0023 SETMBR R4 R3 R5 - 0x80000000, // 0024 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_page_cur_parsing -********************************************************************/ -be_local_closure(class_HASPmota_get_page_cur_parsing, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(get_page_cur_parsing), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040105, // 0000 GETMBR R1 R0 K5 - 0x88080103, // 0001 GETMBR R2 R0 K3 - 0x94040202, // 0002 GETIDX R1 R1 R2 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pages_list_sorted -********************************************************************/ -be_local_closure(class_HASPmota_pages_list_sorted, /* name */ - be_nested_proto( - 8, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(pages_list_sorted), - &be_const_str_solidified, - ( &(const binstruction[47]) { /* code */ - 0x60080012, // 0000 GETGBL R2 G18 - 0x7C080000, // 0001 CALL R2 0 - 0x1C0C030A, // 0002 EQ R3 R1 K10 - 0x780E0000, // 0003 JMPF R3 #0005 - 0x88040104, // 0004 GETMBR R1 R0 K4 - 0x600C0010, // 0005 GETGBL R3 G16 - 0x88100105, // 0006 GETMBR R4 R0 K5 - 0x8C100926, // 0007 GETMET R4 R4 K38 - 0x7C100200, // 0008 CALL R4 1 - 0x7C0C0200, // 0009 CALL R3 1 - 0xA8020007, // 000A EXBLK 0 #0013 - 0x5C100600, // 000B MOVE R4 R3 - 0x7C100000, // 000C CALL R4 0 - 0x2014090A, // 000D NE R5 R4 K10 - 0x78160002, // 000E JMPF R5 #0012 - 0x8C140531, // 000F GETMET R5 R2 K49 - 0x5C1C0800, // 0010 MOVE R7 R4 - 0x7C140400, // 0011 CALL R5 2 - 0x7001FFF7, // 0012 JMP #000B - 0x580C0027, // 0013 LDCONST R3 K39 - 0xAC0C0200, // 0014 CATCH R3 1 0 - 0xB0080000, // 0015 RAISE 2 R0 R0 - 0x8C0C0132, // 0016 GETMET R3 R0 K50 - 0x5C140400, // 0017 MOVE R5 R2 - 0x7C0C0400, // 0018 CALL R3 2 - 0x5C080600, // 0019 MOVE R2 R3 - 0x4C0C0000, // 001A LDNIL R3 - 0x1C0C0203, // 001B EQ R3 R1 R3 - 0x780E0000, // 001C JMPF R3 #001E - 0x80040400, // 001D RET 1 R2 - 0x600C000C, // 001E GETGBL R3 G12 - 0x5C100400, // 001F MOVE R4 R2 - 0x7C0C0200, // 0020 CALL R3 1 - 0x00080402, // 0021 ADD R2 R2 R2 - 0x8C100508, // 0022 GETMET R4 R2 K8 - 0x5C180200, // 0023 MOVE R6 R1 - 0x7C100400, // 0024 CALL R4 2 - 0x4C140000, // 0025 LDNIL R5 - 0x1C140805, // 0026 EQ R5 R4 R5 - 0x78160001, // 0027 JMPF R5 #002A - 0x4C140000, // 0028 LDNIL R5 - 0x80040A00, // 0029 RET 1 R5 - 0x00140803, // 002A ADD R5 R4 R3 - 0x04140B11, // 002B SUB R5 R5 K17 - 0x40140805, // 002C CONNECT R5 R4 R5 - 0x94080405, // 002D GETIDX R2 R2 R5 - 0x80040400, // 002E RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: event_dispatch -********************************************************************/ -be_local_closure(class_HASPmota_event_dispatch, /* name */ - be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(event_dispatch), - &be_const_str_solidified, - ( &(const binstruction[34]) { /* code */ - 0xA40A2E00, // 0000 IMPORT R2 K23 - 0x8C0C0533, // 0001 GETMET R3 R2 K51 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x88100134, // 0004 GETMBR R4 R0 K52 - 0x78120002, // 0005 JMPF R4 #0009 - 0x88100134, // 0006 GETMBR R4 R0 K52 - 0x90126A03, // 0007 SETMBR R4 K53 R3 - 0x70020004, // 0008 JMP #000E - 0xB8126C00, // 0009 GETNGBL R4 K54 - 0x8C100937, // 000A GETMET R4 R4 K55 - 0x5C180600, // 000B MOVE R6 R3 - 0x7C100400, // 000C CALL R4 2 - 0x90026804, // 000D SETMBR R0 K52 R4 - 0x88100134, // 000E GETMBR R4 R0 K52 - 0x8C100938, // 000F GETMET R4 R4 K56 - 0x7C100200, // 0010 CALL R4 1 - 0x60140009, // 0011 GETGBL R5 G9 - 0x5C180800, // 0012 MOVE R6 R4 - 0x7C140200, // 0013 CALL R5 1 - 0x20140B0A, // 0014 NE R5 R5 K10 - 0x7816000A, // 0015 JMPF R5 #0021 - 0x8C140539, // 0016 GETMET R5 R2 K57 - 0x5C1C0800, // 0017 MOVE R7 R4 - 0x7C140400, // 0018 CALL R5 2 - 0x60180004, // 0019 GETGBL R6 G4 - 0x5C1C0A00, // 001A MOVE R7 R5 - 0x7C180200, // 001B CALL R6 1 - 0x1C180D3A, // 001C EQ R6 R6 K58 - 0x781A0002, // 001D JMPF R6 #0021 - 0x8C180B3B, // 001E GETMET R6 R5 K59 - 0x88200134, // 001F GETMBR R8 R0 K52 - 0x7C180400, // 0020 CALL R6 2 - 0x80000000, // 0021 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_page_cur -********************************************************************/ -be_local_closure(class_HASPmota_get_page_cur, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(get_page_cur), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040105, // 0000 GETMBR R1 R0 K5 - 0x88080104, // 0001 GETMBR R2 R0 K4 - 0x94040202, // 0002 GETIDX R1 R1 R2 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: fix_lv_version -********************************************************************/ -be_local_closure(class_HASPmota_fix_lv_version, /* name */ - be_nested_proto( - 6, /* nstack */ - 0, /* argc */ - 12, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(fix_lv_version), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x5800003C, // 0000 LDCONST R0 K60 - 0xA4062E00, // 0001 IMPORT R1 K23 - 0x8C08031E, // 0002 GETMET R2 R1 K30 - 0xB8126C00, // 0003 GETNGBL R4 K54 - 0x5814003D, // 0004 LDCONST R5 K61 - 0x7C080600, // 0005 CALL R2 3 - 0x600C0004, // 0006 GETGBL R3 G4 - 0x5C100400, // 0007 MOVE R4 R2 - 0x7C0C0200, // 0008 CALL R3 1 - 0x200C0702, // 0009 NE R3 R3 K2 - 0x780E0002, // 000A JMPF R3 #000E - 0xB80E6C00, // 000B GETNGBL R3 K54 - 0x54120007, // 000C LDINT R4 8 - 0x900E7A04, // 000D SETMBR R3 K61 R4 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: register_event ********************************************************************/ @@ -11890,21 +11267,21 @@ be_local_closure(class_HASPmota_register_event, /* name */ be_str_weak(register_event), &be_const_str_solidified, ( &(const binstruction[20]) { /* code */ - 0xA40E7C00, // 0000 IMPORT R3 K62 - 0xA4122E00, // 0001 IMPORT R4 K23 - 0x8814013B, // 0002 GETMBR R5 R0 K59 + 0xA40E1C00, // 0000 IMPORT R3 K14 + 0xA4121E00, // 0001 IMPORT R4 K15 + 0x88140110, // 0002 GETMBR R5 R0 K16 0x4C180000, // 0003 LDNIL R6 0x1C140A06, // 0004 EQ R5 R5 R6 0x78160003, // 0005 JMPF R5 #000A - 0x8C14073F, // 0006 GETMET R5 R3 K63 + 0x8C140711, // 0006 GETMET R5 R3 K17 0x841C0000, // 0007 CLOSURE R7 P0 0x7C140400, // 0008 CALL R5 2 - 0x90027605, // 0009 SETMBR R0 K59 R5 - 0x8814031C, // 000A GETMBR R5 R1 K28 - 0x8C180B40, // 000B GETMET R6 R5 K64 - 0x8820013B, // 000C GETMBR R8 R0 K59 + 0x90022005, // 0009 SETMBR R0 K16 R5 + 0x88140312, // 000A GETMBR R5 R1 K18 + 0x8C180B13, // 000B GETMET R6 R5 K19 + 0x88200110, // 000C GETMBR R8 R0 K16 0x5C240400, // 000D MOVE R9 R2 - 0x8C280933, // 000E GETMET R10 R4 K51 + 0x8C280914, // 000E GETMET R10 R4 K20 0x5C300200, // 000F MOVE R12 R1 0x7C280400, // 0010 CALL R10 2 0x7C180800, // 0011 CALL R6 4 @@ -11917,9 +11294,131 @@ be_local_closure(class_HASPmota_register_event, /* name */ /******************************************************************** -** Solidified function: parse +** Solidified function: _load ********************************************************************/ -be_local_closure(class_HASPmota_parse, /* name */ +be_local_closure(class_HASPmota__load, /* name */ + be_nested_proto( + 14, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(_load), + &be_const_str_solidified, + ( &(const binstruction[99]) { /* code */ + 0xA40A2A00, // 0000 IMPORT R2 K21 + 0xA40E2C00, // 0001 IMPORT R3 K22 + 0x60100011, // 0002 GETGBL R4 G17 + 0x5C140200, // 0003 MOVE R5 R1 + 0x58180017, // 0004 LDCONST R6 K23 + 0x7C100400, // 0005 CALL R4 2 + 0x8C140918, // 0006 GETMET R5 R4 K24 + 0x7C140200, // 0007 CALL R5 1 + 0x8C180919, // 0008 GETMET R6 R4 K25 + 0x7C180200, // 0009 CALL R6 1 + 0x8C18051A, // 000A GETMET R6 R2 K26 + 0x5C200A00, // 000B MOVE R8 R5 + 0x5824001B, // 000C LDCONST R9 K27 + 0x7C180600, // 000D CALL R6 3 + 0x4C100000, // 000E LDNIL R4 + 0x4C140000, // 000F LDNIL R5 + 0x601C000C, // 0010 GETGBL R7 G12 + 0x5C200C00, // 0011 MOVE R8 R6 + 0x7C1C0200, // 0012 CALL R7 1 + 0x241C0F07, // 0013 GT R7 R7 K7 + 0x781E0039, // 0014 JMPF R7 #004F + 0x8C1C071C, // 0015 GETMET R7 R3 K28 + 0x94240D07, // 0016 GETIDX R9 R6 K7 + 0x7C1C0400, // 0017 CALL R7 2 + 0x60200004, // 0018 GETGBL R8 G4 + 0x5C240E00, // 0019 MOVE R9 R7 + 0x7C200200, // 001A CALL R8 1 + 0x1C20111D, // 001B EQ R8 R8 K29 + 0x7822001B, // 001C JMPF R8 #0039 + 0xB8223C00, // 001D GETNGBL R8 K30 + 0x8C20111F, // 001E GETMET R8 R8 K31 + 0x542A0003, // 001F LDINT R10 4 + 0x7C200400, // 0020 CALL R8 2 + 0x78220007, // 0021 JMPF R8 #002A + 0xB8223C00, // 0022 GETNGBL R8 K30 + 0x8C201120, // 0023 GETMET R8 R8 K32 + 0x60280018, // 0024 GETGBL R10 G24 + 0x582C0021, // 0025 LDCONST R11 K33 + 0x94300D07, // 0026 GETIDX R12 R6 K7 + 0x7C280400, // 0027 CALL R10 2 + 0x542E0003, // 0028 LDINT R11 4 + 0x7C200600, // 0029 CALL R8 3 + 0x8C200122, // 002A GETMET R8 R0 K34 + 0x5C280E00, // 002B MOVE R10 R7 + 0x7C200400, // 002C CALL R8 2 + 0x8820010C, // 002D GETMBR R8 R0 K12 + 0x4C240000, // 002E LDNIL R9 + 0x1C201009, // 002F EQ R8 R8 R9 + 0x78220000, // 0030 JMPF R8 #0032 + 0xB0064724, // 0031 RAISE 1 K35 K36 + 0x8C200125, // 0032 GETMET R8 R0 K37 + 0x5C280E00, // 0033 MOVE R10 R7 + 0x882C010C, // 0034 GETMBR R11 R0 K12 + 0x88300126, // 0035 GETMBR R12 R0 K38 + 0x942C160C, // 0036 GETIDX R11 R11 R12 + 0x7C200600, // 0037 CALL R8 3 + 0x70020010, // 0038 JMP #004A + 0x6020000C, // 0039 GETGBL R8 G12 + 0x8C240527, // 003A GETMET R9 R2 K39 + 0x942C0D07, // 003B GETIDX R11 R6 K7 + 0x58300028, // 003C LDCONST R12 K40 + 0x58340029, // 003D LDCONST R13 K41 + 0x7C240800, // 003E CALL R9 4 + 0x7C200200, // 003F CALL R8 1 + 0x24201107, // 0040 GT R8 R8 K7 + 0x78220007, // 0041 JMPF R8 #004A + 0xB8223C00, // 0042 GETNGBL R8 K30 + 0x8C201120, // 0043 GETMET R8 R8 K32 + 0x60280018, // 0044 GETGBL R10 G24 + 0x582C002A, // 0045 LDCONST R11 K42 + 0x94300D07, // 0046 GETIDX R12 R6 K7 + 0x7C280400, // 0047 CALL R10 2 + 0x582C002B, // 0048 LDCONST R11 K43 + 0x7C200600, // 0049 CALL R8 3 + 0x4C1C0000, // 004A LDNIL R7 + 0x8C200D2C, // 004B GETMET R8 R6 K44 + 0x58280007, // 004C LDCONST R10 K7 + 0x7C200400, // 004D CALL R8 2 + 0x7001FFC0, // 004E JMP #0010 + 0x4C180000, // 004F LDNIL R6 + 0x8C1C0101, // 0050 GETMET R7 R0 K1 + 0x4C240000, // 0051 LDNIL R9 + 0x7C1C0400, // 0052 CALL R7 2 + 0x6020000C, // 0053 GETGBL R8 G12 + 0x5C240E00, // 0054 MOVE R9 R7 + 0x7C200200, // 0055 CALL R8 1 + 0x1C201107, // 0056 EQ R8 R8 K7 + 0x78220000, // 0057 JMPF R8 #0059 + 0xB006472D, // 0058 RAISE 1 K35 K45 + 0x94200F07, // 0059 GETIDX R8 R7 K7 + 0x90020408, // 005A SETMBR R0 K2 R8 + 0x8820010C, // 005B GETMBR R8 R0 K12 + 0x88240102, // 005C GETMBR R9 R0 K2 + 0x94201009, // 005D GETIDX R8 R8 R9 + 0x8C20110D, // 005E GETMET R8 R8 K13 + 0x58280007, // 005F LDCONST R10 K7 + 0x582C0007, // 0060 LDCONST R11 K7 + 0x7C200600, // 0061 CALL R8 3 + 0x80000000, // 0062 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_dispatch +********************************************************************/ +be_local_closure(class_HASPmota_event_dispatch, /* name */ be_nested_proto( 9, /* nstack */ 2, /* argc */ @@ -11930,30 +11429,108 @@ be_local_closure(class_HASPmota_parse, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(parse), + be_str_weak(event_dispatch), &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0xA40A8200, // 0000 IMPORT R2 K65 - 0x8C0C0542, // 0001 GETMET R3 R2 K66 + ( &(const binstruction[34]) { /* code */ + 0xA40A1E00, // 0000 IMPORT R2 K15 + 0x8C0C0514, // 0001 GETMET R3 R2 K20 0x5C140200, // 0002 MOVE R5 R1 0x7C0C0400, // 0003 CALL R3 2 - 0x60100004, // 0004 GETGBL R4 G4 - 0x5C140600, // 0005 MOVE R5 R3 - 0x7C100200, // 0006 CALL R4 1 - 0x1C10093A, // 0007 EQ R4 R4 K58 - 0x78120009, // 0008 JMPF R4 #0013 - 0x8C100143, // 0009 GETMET R4 R0 K67 - 0x5C180600, // 000A MOVE R6 R3 - 0x7C100400, // 000B CALL R4 2 - 0x8C100144, // 000C GETMET R4 R0 K68 - 0x5C180600, // 000D MOVE R6 R3 - 0x881C0105, // 000E GETMBR R7 R0 K5 - 0x88200104, // 000F GETMBR R8 R0 K4 - 0x941C0E08, // 0010 GETIDX R7 R7 R8 - 0x7C100600, // 0011 CALL R4 3 - 0x70020000, // 0012 JMP #0014 - 0xB0068B46, // 0013 RAISE 1 K69 K70 - 0x80000000, // 0014 RET 0 + 0x8810012E, // 0004 GETMBR R4 R0 K46 + 0x78120002, // 0005 JMPF R4 #0009 + 0x8810012E, // 0006 GETMBR R4 R0 K46 + 0x90125E03, // 0007 SETMBR R4 K47 R3 + 0x70020004, // 0008 JMP #000E + 0xB8126000, // 0009 GETNGBL R4 K48 + 0x8C100931, // 000A GETMET R4 R4 K49 + 0x5C180600, // 000B MOVE R6 R3 + 0x7C100400, // 000C CALL R4 2 + 0x90025C04, // 000D SETMBR R0 K46 R4 + 0x8810012E, // 000E GETMBR R4 R0 K46 + 0x8C100932, // 000F GETMET R4 R4 K50 + 0x7C100200, // 0010 CALL R4 1 + 0x60140009, // 0011 GETGBL R5 G9 + 0x5C180800, // 0012 MOVE R6 R4 + 0x7C140200, // 0013 CALL R5 1 + 0x20140B07, // 0014 NE R5 R5 K7 + 0x7816000A, // 0015 JMPF R5 #0021 + 0x8C140533, // 0016 GETMET R5 R2 K51 + 0x5C1C0800, // 0017 MOVE R7 R4 + 0x7C140400, // 0018 CALL R5 2 + 0x60180004, // 0019 GETGBL R6 G4 + 0x5C1C0A00, // 001A MOVE R7 R5 + 0x7C180200, // 001B CALL R6 1 + 0x1C180D1D, // 001C EQ R6 R6 K29 + 0x781A0002, // 001D JMPF R6 #0021 + 0x8C180B10, // 001E GETMET R6 R5 K16 + 0x8820012E, // 001F GETMBR R8 R0 K46 + 0x7C180400, // 0020 CALL R6 2 + 0x80000000, // 0021 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: fix_lv_version +********************************************************************/ +be_local_closure(class_HASPmota_fix_lv_version, /* name */ + be_nested_proto( + 6, /* nstack */ + 0, /* argc */ + 12, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(fix_lv_version), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x58000034, // 0000 LDCONST R0 K52 + 0xA4061E00, // 0001 IMPORT R1 K15 + 0x8C080335, // 0002 GETMET R2 R1 K53 + 0xB8126000, // 0003 GETNGBL R4 K48 + 0x58140036, // 0004 LDCONST R5 K54 + 0x7C080600, // 0005 CALL R2 3 + 0x600C0004, // 0006 GETGBL R3 G4 + 0x5C100400, // 0007 MOVE R4 R2 + 0x7C0C0200, // 0008 CALL R3 1 + 0x200C0737, // 0009 NE R3 R3 K55 + 0x780E0002, // 000A JMPF R3 #000E + 0xB80E6000, // 000B GETNGBL R3 K48 + 0x54120007, // 000C LDINT R4 8 + 0x900E6C04, // 000D SETMBR R3 K54 R4 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_page_cur_parsing +********************************************************************/ +be_local_closure(class_HASPmota_get_page_cur_parsing, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(get_page_cur_parsing), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8804010C, // 0000 GETMBR R1 R0 K12 + 0x88080126, // 0001 GETMBR R2 R0 K38 + 0x94040202, // 0002 GETIDX R1 R1 R2 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -11977,13 +11554,13 @@ be_local_closure(class_HASPmota_init, /* name */ be_str_weak(init), &be_const_str_solidified, ( &(const binstruction[ 8]) { /* code */ - 0x8C040147, // 0000 GETMET R1 R0 K71 + 0x8C040138, // 0000 GETMET R1 R0 K56 0x7C040200, // 0001 CALL R1 1 - 0xA4069000, // 0002 IMPORT R1 K72 - 0x8C080349, // 0003 GETMET R2 R1 K73 - 0x5810004A, // 0004 LDCONST R4 K74 + 0xA4067200, // 0002 IMPORT R1 K57 + 0x8C08033A, // 0003 GETMET R2 R1 K58 + 0x5810003B, // 0004 LDCONST R4 K59 0x7C080400, // 0005 CALL R2 2 - 0x90022602, // 0006 SETMBR R0 K19 R2 + 0x90021402, // 0006 SETMBR R0 K10 R2 0x80000000, // 0007 RET 0 }) ) @@ -11991,6 +11568,358 @@ be_local_closure(class_HASPmota_init, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: pages_list_sorted +********************************************************************/ +be_local_closure(class_HASPmota_pages_list_sorted, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(pages_list_sorted), + &be_const_str_solidified, + ( &(const binstruction[47]) { /* code */ + 0x60080012, // 0000 GETGBL R2 G18 + 0x7C080000, // 0001 CALL R2 0 + 0x1C0C0307, // 0002 EQ R3 R1 K7 + 0x780E0000, // 0003 JMPF R3 #0005 + 0x88040102, // 0004 GETMBR R1 R0 K2 + 0x600C0010, // 0005 GETGBL R3 G16 + 0x8810010C, // 0006 GETMBR R4 R0 K12 + 0x8C10093C, // 0007 GETMET R4 R4 K60 + 0x7C100200, // 0008 CALL R4 1 + 0x7C0C0200, // 0009 CALL R3 1 + 0xA8020007, // 000A EXBLK 0 #0013 + 0x5C100600, // 000B MOVE R4 R3 + 0x7C100000, // 000C CALL R4 0 + 0x20140907, // 000D NE R5 R4 K7 + 0x78160002, // 000E JMPF R5 #0012 + 0x8C14053D, // 000F GETMET R5 R2 K61 + 0x5C1C0800, // 0010 MOVE R7 R4 + 0x7C140400, // 0011 CALL R5 2 + 0x7001FFF7, // 0012 JMP #000B + 0x580C003E, // 0013 LDCONST R3 K62 + 0xAC0C0200, // 0014 CATCH R3 1 0 + 0xB0080000, // 0015 RAISE 2 R0 R0 + 0x8C0C013F, // 0016 GETMET R3 R0 K63 + 0x5C140400, // 0017 MOVE R5 R2 + 0x7C0C0400, // 0018 CALL R3 2 + 0x5C080600, // 0019 MOVE R2 R3 + 0x4C0C0000, // 001A LDNIL R3 + 0x1C0C0203, // 001B EQ R3 R1 R3 + 0x780E0000, // 001C JMPF R3 #001E + 0x80040400, // 001D RET 1 R2 + 0x600C000C, // 001E GETGBL R3 G12 + 0x5C100400, // 001F MOVE R4 R2 + 0x7C0C0200, // 0020 CALL R3 1 + 0x00080402, // 0021 ADD R2 R2 R2 + 0x8C100540, // 0022 GETMET R4 R2 K64 + 0x5C180200, // 0023 MOVE R6 R1 + 0x7C100400, // 0024 CALL R4 2 + 0x4C140000, // 0025 LDNIL R5 + 0x1C140805, // 0026 EQ R5 R4 R5 + 0x78160001, // 0027 JMPF R5 #002A + 0x4C140000, // 0028 LDNIL R5 + 0x80040A00, // 0029 RET 1 R5 + 0x00140803, // 002A ADD R5 R4 R3 + 0x04140B03, // 002B SUB R5 R5 K3 + 0x40140805, // 002C CONNECT R5 R4 R5 + 0x94080405, // 002D GETIDX R2 R2 R5 + 0x80040400, // 002E RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: sort +********************************************************************/ +be_local_closure(class_HASPmota_sort, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 12, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(sort), + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0x58040034, // 0000 LDCONST R1 K52 + 0x60080010, // 0001 GETGBL R2 G16 + 0x600C000C, // 0002 GETGBL R3 G12 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C0C0200, // 0004 CALL R3 1 + 0x040C0703, // 0005 SUB R3 R3 K3 + 0x400E0603, // 0006 CONNECT R3 K3 R3 + 0x7C080200, // 0007 CALL R2 1 + 0xA8020010, // 0008 EXBLK 0 #001A + 0x5C0C0400, // 0009 MOVE R3 R2 + 0x7C0C0000, // 000A CALL R3 0 + 0x94100003, // 000B GETIDX R4 R0 R3 + 0x5C140600, // 000C MOVE R5 R3 + 0x24180B07, // 000D GT R6 R5 K7 + 0x781A0008, // 000E JMPF R6 #0018 + 0x04180B03, // 000F SUB R6 R5 K3 + 0x94180006, // 0010 GETIDX R6 R0 R6 + 0x24180C04, // 0011 GT R6 R6 R4 + 0x781A0004, // 0012 JMPF R6 #0018 + 0x04180B03, // 0013 SUB R6 R5 K3 + 0x94180006, // 0014 GETIDX R6 R0 R6 + 0x98000A06, // 0015 SETIDX R0 R5 R6 + 0x04140B03, // 0016 SUB R5 R5 K3 + 0x7001FFF4, // 0017 JMP #000D + 0x98000A04, // 0018 SETIDX R0 R5 R4 + 0x7001FFEE, // 0019 JMP #0009 + 0x5808003E, // 001A LDCONST R2 K62 + 0xAC080200, // 001B CATCH R2 1 0 + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x80040000, // 001D RET 1 R0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: _remove_page +********************************************************************/ +be_local_closure(class_HASPmota__remove_page, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(_remove_page), + &be_const_str_solidified, + ( &(const binstruction[37]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x7C080200, // 0001 CALL R2 1 + 0x8C080509, // 0002 GETMET R2 R2 K9 + 0x7C080200, // 0003 CALL R2 1 + 0x1C0C0202, // 0004 EQ R3 R1 R2 + 0x780E0008, // 0005 JMPF R3 #000F + 0x8C0C0141, // 0006 GETMET R3 R0 K65 + 0x58140008, // 0007 LDCONST R5 K8 + 0x58180007, // 0008 LDCONST R6 K7 + 0x581C0007, // 0009 LDCONST R7 K7 + 0x7C0C0800, // 000A CALL R3 4 + 0x4C100000, // 000B LDNIL R4 + 0x1C100604, // 000C EQ R4 R3 R4 + 0x78120000, // 000D JMPF R4 #000F + 0x80000800, // 000E RET 0 + 0x880C0126, // 000F GETMBR R3 R0 K38 + 0x1C0C0601, // 0010 EQ R3 R3 R1 + 0x780E0001, // 0011 JMPF R3 #0014 + 0x880C0102, // 0012 GETMBR R3 R0 K2 + 0x90024C03, // 0013 SETMBR R0 K38 R3 + 0x880C010C, // 0014 GETMBR R3 R0 K12 + 0x8C0C0742, // 0015 GETMET R3 R3 K66 + 0x5C140200, // 0016 MOVE R5 R1 + 0x7C0C0400, // 0017 CALL R3 2 + 0x780E0003, // 0018 JMPF R3 #001D + 0x880C010C, // 0019 GETMBR R3 R0 K12 + 0x8C0C072C, // 001A GETMET R3 R3 K44 + 0x5C140200, // 001B MOVE R5 R1 + 0x7C0C0400, // 001C CALL R3 2 + 0x600C0018, // 001D GETGBL R3 G24 + 0x58100044, // 001E LDCONST R4 K68 + 0x5C140200, // 001F MOVE R5 R1 + 0x7C0C0400, // 0020 CALL R3 2 + 0xB8128600, // 0021 GETNGBL R4 K67 + 0x4C140000, // 0022 LDNIL R5 + 0x90100605, // 0023 SETMBR R4 R3 R5 + 0x80000000, // 0024 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: do_action +********************************************************************/ +be_local_closure(class_HASPmota_do_action, /* name */ + be_nested_proto( + 6, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(do_action), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0xB80E6000, // 0000 GETNGBL R3 K48 + 0x880C0745, // 0001 GETMBR R3 R3 K69 + 0x200C0403, // 0002 NE R3 R2 R3 + 0x780E0000, // 0003 JMPF R3 #0005 + 0x80000600, // 0004 RET 0 + 0x8C0C0141, // 0005 GETMET R3 R0 K65 + 0x88140346, // 0006 GETMBR R5 R1 K70 + 0x7C0C0400, // 0007 CALL R3 2 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_page +********************************************************************/ +be_local_closure(class_HASPmota_parse_page, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(parse_page), + &be_const_str_solidified, + ( &(const binstruction[59]) { /* code */ + 0x8C080347, // 0000 GETMET R2 R1 K71 + 0x58100048, // 0001 LDCONST R4 K72 + 0x7C080400, // 0002 CALL R2 2 + 0x780A0035, // 0003 JMPF R2 #003A + 0x60080004, // 0004 GETGBL R2 G4 + 0x940C0348, // 0005 GETIDX R3 R1 K72 + 0x7C080200, // 0006 CALL R2 1 + 0x1C080537, // 0007 EQ R2 R2 K55 + 0x780A0030, // 0008 JMPF R2 #003A + 0x60080009, // 0009 GETGBL R2 G9 + 0x940C0348, // 000A GETIDX R3 R1 K72 + 0x7C080200, // 000B CALL R2 1 + 0x90024C02, // 000C SETMBR R0 K38 R2 + 0x880C0102, // 000D GETMBR R3 R0 K2 + 0x4C100000, // 000E LDNIL R4 + 0x1C0C0604, // 000F EQ R3 R3 R4 + 0x780E0000, // 0010 JMPF R3 #0012 + 0x90020402, // 0011 SETMBR R0 K2 R2 + 0x880C010C, // 0012 GETMBR R3 R0 K12 + 0x8C0C0742, // 0013 GETMET R3 R3 K66 + 0x5C140400, // 0014 MOVE R5 R2 + 0x7C0C0400, // 0015 CALL R3 2 + 0x740E0006, // 0016 JMPT R3 #001E + 0x880C0149, // 0017 GETMBR R3 R0 K73 + 0x8810010C, // 0018 GETMBR R4 R0 K12 + 0x5C140600, // 0019 MOVE R5 R3 + 0x5C180400, // 001A MOVE R6 R2 + 0x5C1C0000, // 001B MOVE R7 R0 + 0x7C140400, // 001C CALL R5 2 + 0x98100405, // 001D SETIDX R4 R2 R5 + 0x8C0C0340, // 001E GETMET R3 R1 K64 + 0x58140009, // 001F LDCONST R5 K9 + 0x7C0C0400, // 0020 CALL R3 2 + 0x1C0C0707, // 0021 EQ R3 R3 K7 + 0x780E0016, // 0022 JMPF R3 #003A + 0x8C0C014A, // 0023 GETMET R3 R0 K74 + 0x7C0C0200, // 0024 CALL R3 1 + 0x60100009, // 0025 GETGBL R4 G9 + 0x8C140340, // 0026 GETMET R5 R1 K64 + 0x581C0004, // 0027 LDCONST R7 K4 + 0x4C200000, // 0028 LDNIL R8 + 0x7C140600, // 0029 CALL R5 3 + 0x7C100200, // 002A CALL R4 1 + 0x900E0804, // 002B SETMBR R3 K4 R4 + 0x60100009, // 002C GETGBL R4 G9 + 0x8C140340, // 002D GETMET R5 R1 K64 + 0x581C0005, // 002E LDCONST R7 K5 + 0x4C200000, // 002F LDNIL R8 + 0x7C140600, // 0030 CALL R5 3 + 0x7C100200, // 0031 CALL R4 1 + 0x900E0A04, // 0032 SETMBR R3 K5 R4 + 0x60100009, // 0033 GETGBL R4 G9 + 0x8C140340, // 0034 GETMET R5 R1 K64 + 0x581C0006, // 0035 LDCONST R7 K6 + 0x4C200000, // 0036 LDNIL R8 + 0x7C140600, // 0037 CALL R5 3 + 0x7C100200, // 0038 CALL R4 1 + 0x900E0C04, // 0039 SETMBR R3 K6 R4 + 0x80000000, // 003A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: page_dir_to +********************************************************************/ +be_local_closure(class_HASPmota_page_dir_to, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(page_dir_to), + &be_const_str_solidified, + ( &(const binstruction[32]) { /* code */ + 0x8C080101, // 0000 GETMET R2 R0 K1 + 0x58100007, // 0001 LDCONST R4 K7 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x1C0C0403, // 0004 EQ R3 R2 R3 + 0x780E0000, // 0005 JMPF R3 #0007 + 0x80060E00, // 0006 RET 1 K7 + 0x600C000C, // 0007 GETGBL R3 G12 + 0x5C100400, // 0008 MOVE R4 R2 + 0x7C0C0200, // 0009 CALL R3 1 + 0x18100703, // 000A LE R4 R3 K3 + 0x78120000, // 000B JMPF R4 #000D + 0x80060E00, // 000C RET 1 K7 + 0x1C10072B, // 000D EQ R4 R3 K43 + 0x78120000, // 000E JMPF R4 #0010 + 0x80060600, // 000F RET 1 K3 + 0x8C100540, // 0010 GETMET R4 R2 K64 + 0x5C180200, // 0011 MOVE R6 R1 + 0x7C100400, // 0012 CALL R4 2 + 0x4C140000, // 0013 LDNIL R5 + 0x1C140805, // 0014 EQ R5 R4 R5 + 0x78160000, // 0015 JMPF R5 #0017 + 0x80060E00, // 0016 RET 1 K7 + 0x00140703, // 0017 ADD R5 R3 K3 + 0x0C140B2B, // 0018 DIV R5 R5 K43 + 0x18140805, // 0019 LE R5 R4 R5 + 0x78160001, // 001A JMPF R5 #001D + 0x80060600, // 001B RET 1 K3 + 0x70020001, // 001C JMP #001F + 0x5415FFFE, // 001D LDINT R5 -1 + 0x80040A00, // 001E RET 1 R5 + 0x80000000, // 001F RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: start ********************************************************************/ @@ -12020,27 +11949,27 @@ be_local_closure(class_HASPmota_start, /* name */ 0x00129C02, // 0009 ADD R4 K78 R2 0x0010094F, // 000A ADD R4 R4 K79 0xB006A004, // 000B RAISE 1 K80 R4 - 0xB8126C00, // 000C GETNGBL R4 K54 + 0xB8126000, // 000C GETNGBL R4 K48 0x8C100951, // 000D GETMET R4 R4 K81 0x7C100200, // 000E CALL R4 1 0x60100017, // 000F GETGBL R4 G23 0x5C140200, // 0010 MOVE R5 R1 0x7C100200, // 0011 CALL R4 1 0x9002A404, // 0012 SETMBR R0 K82 R4 - 0xB8126C00, // 0013 GETNGBL R4 K54 + 0xB8126000, // 0013 GETNGBL R4 K48 0x8C100954, // 0014 GETMET R4 R4 K84 0x7C100200, // 0015 CALL R4 1 0x9002A604, // 0016 SETMBR R0 K83 R4 - 0xB8126C00, // 0017 GETNGBL R4 K54 + 0xB8126000, // 0017 GETNGBL R4 K48 0x8C100956, // 0018 GETMET R4 R4 K86 0x7C100200, // 0019 CALL R4 1 0x9002AA04, // 001A SETMBR R0 K85 R4 - 0xB8126C00, // 001B GETNGBL R4 K54 + 0xB8126000, // 001B GETNGBL R4 K48 0x8C100958, // 001C GETMET R4 R4 K88 0x7C100200, // 001D CALL R4 1 0x9002AE04, // 001E SETMBR R0 K87 R4 0xA8020007, // 001F EXBLK 0 #0028 - 0xB8126C00, // 0020 GETNGBL R4 K54 + 0xB8126000, // 0020 GETNGBL R4 K48 0x8C10095A, // 0021 GETMET R4 R4 K90 0x5818005B, // 0022 LDCONST R6 K91 0x541E000F, // 0023 LDINT R7 16 @@ -12050,7 +11979,7 @@ be_local_closure(class_HASPmota_start, /* name */ 0x70020009, // 0027 JMP #0032 0xAC100000, // 0028 CATCH R4 0 0 0x70020006, // 0029 JMP #0031 - 0xB8126C00, // 002A GETNGBL R4 K54 + 0xB8126000, // 002A GETNGBL R4 K48 0x8C10095A, // 002B GETMET R4 R4 K90 0x5818005C, // 002C LDCONST R6 K92 0x541E000D, // 002D LDINT R7 14 @@ -12058,14 +11987,14 @@ be_local_closure(class_HASPmota_start, /* name */ 0x9002B204, // 002F SETMBR R0 K89 R4 0x70020000, // 0030 JMP #0032 0xB0080000, // 0031 RAISE 2 R0 R0 - 0xB8126C00, // 0032 GETNGBL R4 K54 + 0xB8126000, // 0032 GETNGBL R4 K48 0x8C10095D, // 0033 GETMET R4 R4 K93 - 0x5818000A, // 0034 LDCONST R6 K10 - 0xB81E6C00, // 0035 GETNGBL R7 K54 + 0x58180007, // 0034 LDCONST R6 K7 + 0xB81E6000, // 0035 GETNGBL R7 K48 0x8C1C0F5E, // 0036 GETMET R7 R7 K94 0x5824005F, // 0037 LDCONST R9 K95 0x7C1C0400, // 0038 CALL R7 2 - 0xB8226C00, // 0039 GETNGBL R8 K54 + 0xB8226000, // 0039 GETNGBL R8 K48 0x8C20115E, // 003A GETMET R8 R8 K94 0x58280060, // 003B LDCONST R10 K96 0x7C200400, // 003C CALL R8 2 @@ -12082,33 +12011,33 @@ be_local_closure(class_HASPmota_start, /* name */ 0x8C140B63, // 0047 GETMET R5 R5 K99 0x881C0152, // 0048 GETMBR R7 R0 K82 0x781E0004, // 0049 JMPF R7 #004F - 0xB81E6C00, // 004A GETNGBL R7 K54 + 0xB81E6000, // 004A GETNGBL R7 K48 0x8C1C0F5E, // 004B GETMET R7 R7 K94 - 0x5824000A, // 004C LDCONST R9 K10 + 0x58240007, // 004C LDCONST R9 K7 0x7C1C0400, // 004D CALL R7 2 0x70020003, // 004E JMP #0053 - 0xB81E6C00, // 004F GETNGBL R7 K54 + 0xB81E6000, // 004F GETNGBL R7 K48 0x8C1C0F5E, // 0050 GETMET R7 R7 K94 0x58240064, // 0051 LDCONST R9 K100 0x7C1C0400, // 0052 CALL R7 2 - 0x5820000A, // 0053 LDCONST R8 K10 + 0x58200007, // 0053 LDCONST R8 K7 0x7C140600, // 0054 CALL R5 3 - 0xB8166C00, // 0055 GETNGBL R5 K54 + 0xB8166000, // 0055 GETNGBL R5 K48 0x8C140B65, // 0056 GETMET R5 R5 K101 - 0xB81E6C00, // 0057 GETNGBL R7 K54 + 0xB81E6000, // 0057 GETNGBL R7 K48 0x8C1C0F66, // 0058 GETMET R7 R7 K102 0x7C1C0200, // 0059 CALL R7 1 0x7C140400, // 005A CALL R5 2 - 0xB8166C00, // 005B GETNGBL R5 K54 + 0xB8166000, // 005B GETNGBL R5 K48 0x8C140B66, // 005C GETMET R5 R5 K102 0x7C140200, // 005D CALL R5 1 0x8C140B67, // 005E GETMET R5 R5 K103 - 0x581C000A, // 005F LDCONST R7 K10 - 0x5820000A, // 0060 LDCONST R8 K10 + 0x581C0007, // 005F LDCONST R7 K7 + 0x58200007, // 0060 LDCONST R8 K7 0x7C140600, // 0061 CALL R5 3 0x60140013, // 0062 GETGBL R5 G19 0x7C140000, // 0063 CALL R5 0 - 0x90020A05, // 0064 SETMBR R0 K5 R5 + 0x90021805, // 0064 SETMBR R0 K12 R5 0x8C140168, // 0065 GETMET R5 R0 K104 0x5C1C0400, // 0066 MOVE R7 R2 0x7C140400, // 0067 CALL R5 2 @@ -12120,66 +12049,11 @@ be_local_closure(class_HASPmota_start, /* name */ /******************************************************************** -** Solidified function: page_dir_to +** Solidified function: parse_obj ********************************************************************/ -be_local_closure(class_HASPmota_page_dir_to, /* name */ +be_local_closure(class_HASPmota_parse_obj, /* name */ be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(page_dir_to), - &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ - 0x8C080110, // 0000 GETMET R2 R0 K16 - 0x5810000A, // 0001 LDCONST R4 K10 - 0x7C080400, // 0002 CALL R2 2 - 0x4C0C0000, // 0003 LDNIL R3 - 0x1C0C0403, // 0004 EQ R3 R2 R3 - 0x780E0000, // 0005 JMPF R3 #0007 - 0x80061400, // 0006 RET 1 K10 - 0x600C000C, // 0007 GETGBL R3 G12 - 0x5C100400, // 0008 MOVE R4 R2 - 0x7C0C0200, // 0009 CALL R3 1 - 0x18100711, // 000A LE R4 R3 K17 - 0x78120000, // 000B JMPF R4 #000D - 0x80061400, // 000C RET 1 K10 - 0x1C100769, // 000D EQ R4 R3 K105 - 0x78120000, // 000E JMPF R4 #0010 - 0x80062200, // 000F RET 1 K17 - 0x8C100508, // 0010 GETMET R4 R2 K8 - 0x5C180200, // 0011 MOVE R6 R1 - 0x7C100400, // 0012 CALL R4 2 - 0x4C140000, // 0013 LDNIL R5 - 0x1C140805, // 0014 EQ R5 R4 R5 - 0x78160000, // 0015 JMPF R5 #0017 - 0x80061400, // 0016 RET 1 K10 - 0x00140711, // 0017 ADD R5 R3 K17 - 0x0C140B69, // 0018 DIV R5 R5 K105 - 0x18140805, // 0019 LE R5 R4 R5 - 0x78160001, // 001A JMPF R5 #001D - 0x80062200, // 001B RET 1 K17 - 0x70020001, // 001C JMP #001F - 0x5415FFFE, // 001D LDINT R5 -1 - 0x80040A00, // 001E RET 1 R5 - 0x80000000, // 001F RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: do_action -********************************************************************/ -be_local_closure(class_HASPmota_do_action, /* name */ - be_nested_proto( - 6, /* nstack */ + 20, /* nstack */ 3, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -12188,18 +12062,248 @@ be_local_closure(class_HASPmota_do_action, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(do_action), + be_str_weak(parse_obj), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0xB80E6C00, // 0000 GETNGBL R3 K54 - 0x880C076A, // 0001 GETMBR R3 R3 K106 - 0x200C0403, // 0002 NE R3 R2 R3 - 0x780E0000, // 0003 JMPF R3 #0005 - 0x80000600, // 0004 RET 0 - 0x8C0C012E, // 0005 GETMET R3 R0 K46 - 0x8814036B, // 0006 GETMBR R5 R1 K107 - 0x7C0C0400, // 0007 CALL R3 2 - 0x80000000, // 0008 RET 0 + ( &(const binstruction[239]) { /* code */ + 0xA40E8600, // 0000 IMPORT R3 K67 + 0xA4121E00, // 0001 IMPORT R4 K15 + 0x60140009, // 0002 GETGBL R5 G9 + 0x8C180340, // 0003 GETMET R6 R1 K64 + 0x58200009, // 0004 LDCONST R8 K9 + 0x7C180400, // 0005 CALL R6 2 + 0x7C140200, // 0006 CALL R5 1 + 0x8C180340, // 0007 GETMET R6 R1 K64 + 0x58200069, // 0008 LDCONST R8 K105 + 0x7C180400, // 0009 CALL R6 2 + 0x4C1C0000, // 000A LDNIL R7 + 0x201C0C07, // 000B NE R7 R6 R7 + 0x781E0003, // 000C JMPF R7 #0011 + 0x601C0008, // 000D GETGBL R7 G8 + 0x5C200C00, // 000E MOVE R8 R6 + 0x7C1C0200, // 000F CALL R7 1 + 0x70020000, // 0010 JMP #0012 + 0x4C1C0000, // 0011 LDNIL R7 + 0x5C180E00, // 0012 MOVE R6 R7 + 0x8C1C014A, // 0013 GETMET R7 R0 K74 + 0x7C1C0200, // 0014 CALL R7 1 + 0x4C200000, // 0015 LDNIL R8 + 0x20200A08, // 0016 NE R8 R5 R8 + 0x78220011, // 0017 JMPF R8 #002A + 0x14200B07, // 0018 LT R8 R5 K7 + 0x74220002, // 0019 JMPT R8 #001D + 0x542200FD, // 001A LDINT R8 254 + 0x24200A08, // 001B GT R8 R5 R8 + 0x7822000C, // 001C JMPF R8 #002A + 0x20200B07, // 001D NE R8 R5 K7 + 0x74220002, // 001E JMPT R8 #0022 + 0x4C200000, // 001F LDNIL R8 + 0x1C200C08, // 0020 EQ R8 R6 R8 + 0x78220007, // 0021 JMPF R8 #002A + 0x60200001, // 0022 GETGBL R8 G1 + 0x60240018, // 0023 GETGBL R9 G24 + 0x5828006A, // 0024 LDCONST R10 K106 + 0x5C2C0A00, // 0025 MOVE R11 R5 + 0x5C300C00, // 0026 MOVE R12 R6 + 0x7C240600, // 0027 CALL R9 3 + 0x7C200200, // 0028 CALL R8 1 + 0x80001000, // 0029 RET 0 + 0x8C200F6B, // 002A GETMET R8 R7 K107 + 0x5C280A00, // 002B MOVE R10 R5 + 0x7C200400, // 002C CALL R8 2 + 0x4C240000, // 002D LDNIL R9 + 0x20240C09, // 002E NE R9 R6 R9 + 0x7826005F, // 002F JMPF R9 #0090 + 0x4C240000, // 0030 LDNIL R9 + 0x20240A09, // 0031 NE R9 R5 R9 + 0x7826005C, // 0032 JMPF R9 #0090 + 0x4C240000, // 0033 LDNIL R9 + 0x1C241009, // 0034 EQ R9 R8 R9 + 0x78260059, // 0035 JMPF R9 #0090 + 0x60240009, // 0036 GETGBL R9 G9 + 0x8C280340, // 0037 GETMET R10 R1 K64 + 0x5830006C, // 0038 LDCONST R12 K108 + 0x7C280400, // 0039 CALL R10 2 + 0x7C240200, // 003A CALL R9 1 + 0x4C280000, // 003B LDNIL R10 + 0x4C2C0000, // 003C LDNIL R11 + 0x4C300000, // 003D LDNIL R12 + 0x2030120C, // 003E NE R12 R9 R12 + 0x78320007, // 003F JMPF R12 #0048 + 0x8C300F6B, // 0040 GETMET R12 R7 K107 + 0x5C381200, // 0041 MOVE R14 R9 + 0x7C300400, // 0042 CALL R12 2 + 0x5C281800, // 0043 MOVE R10 R12 + 0x4C300000, // 0044 LDNIL R12 + 0x2030140C, // 0045 NE R12 R10 R12 + 0x78320000, // 0046 JMPF R12 #0048 + 0x882C1512, // 0047 GETMBR R11 R10 K18 + 0x4C300000, // 0048 LDNIL R12 + 0x1C30160C, // 0049 EQ R12 R11 R12 + 0x78320002, // 004A JMPF R12 #004E + 0x8C300F6D, // 004B GETMET R12 R7 K109 + 0x7C300200, // 004C CALL R12 1 + 0x5C2C1800, // 004D MOVE R11 R12 + 0x8C300935, // 004E GETMET R12 R4 K53 + 0x5C380000, // 004F MOVE R14 R0 + 0x003EDC06, // 0050 ADD R15 K110 R6 + 0x7C300600, // 0051 CALL R12 3 + 0x4C340000, // 0052 LDNIL R13 + 0x4C380000, // 0053 LDNIL R14 + 0x1C38180E, // 0054 EQ R14 R12 R14 + 0x783A0010, // 0055 JMPF R14 #0067 + 0x8C380935, // 0056 GETMET R14 R4 K53 + 0x5C400600, // 0057 MOVE R16 R3 + 0x5C440C00, // 0058 MOVE R17 R6 + 0x7C380600, // 0059 CALL R14 3 + 0x4C3C0000, // 005A LDNIL R15 + 0x203C1C0F, // 005B NE R15 R14 R15 + 0x783E0009, // 005C JMPF R15 #0067 + 0x603C0004, // 005D GETGBL R15 G4 + 0x5C401C00, // 005E MOVE R16 R14 + 0x7C3C0200, // 005F CALL R15 1 + 0x1C3C1F6F, // 0060 EQ R15 R15 K111 + 0x783E0004, // 0061 JMPF R15 #0067 + 0x5C3C1C00, // 0062 MOVE R15 R14 + 0x5C401600, // 0063 MOVE R16 R11 + 0x7C3C0200, // 0064 CALL R15 1 + 0x5C341E00, // 0065 MOVE R13 R15 + 0x88300170, // 0066 GETMBR R12 R0 K112 + 0x4C380000, // 0067 LDNIL R14 + 0x1C38180E, // 0068 EQ R14 R12 R14 + 0x783A000F, // 0069 JMPF R14 #007A + 0x8C380971, // 006A GETMET R14 R4 K113 + 0x5C400C00, // 006B MOVE R16 R6 + 0x7C380400, // 006C CALL R14 2 + 0x4C3C0000, // 006D LDNIL R15 + 0x203C1C0F, // 006E NE R15 R14 R15 + 0x783E0009, // 006F JMPF R15 #007A + 0x603C0004, // 0070 GETGBL R15 G4 + 0x5C401C00, // 0071 MOVE R16 R14 + 0x7C3C0200, // 0072 CALL R15 1 + 0x1C3C1F6F, // 0073 EQ R15 R15 K111 + 0x783E0004, // 0074 JMPF R15 #007A + 0x5C3C1C00, // 0075 MOVE R15 R14 + 0x5C401600, // 0076 MOVE R16 R11 + 0x7C3C0200, // 0077 CALL R15 1 + 0x5C341E00, // 0078 MOVE R13 R15 + 0x88300170, // 0079 GETMBR R12 R0 K112 + 0x4C380000, // 007A LDNIL R14 + 0x1C38180E, // 007B EQ R14 R12 R14 + 0x783A0006, // 007C JMPF R14 #0084 + 0x60380001, // 007D GETGBL R14 G1 + 0x603C0018, // 007E GETGBL R15 G24 + 0x58400072, // 007F LDCONST R16 K114 + 0x5C440C00, // 0080 MOVE R17 R6 + 0x7C3C0400, // 0081 CALL R15 2 + 0x7C380200, // 0082 CALL R14 1 + 0x80001C00, // 0083 RET 0 + 0x5C381800, // 0084 MOVE R14 R12 + 0x5C3C1600, // 0085 MOVE R15 R11 + 0x5C400400, // 0086 MOVE R16 R2 + 0x5C440200, // 0087 MOVE R17 R1 + 0x5C481A00, // 0088 MOVE R18 R13 + 0x5C4C1400, // 0089 MOVE R19 R10 + 0x7C380A00, // 008A CALL R14 5 + 0x5C201C00, // 008B MOVE R8 R14 + 0x8C380F73, // 008C GETMET R14 R7 K115 + 0x5C400A00, // 008D MOVE R16 R5 + 0x5C441000, // 008E MOVE R17 R8 + 0x7C380600, // 008F CALL R14 3 + 0x1C240B07, // 0090 EQ R9 R5 K7 + 0x7826000F, // 0091 JMPF R9 #00A2 + 0x4C240000, // 0092 LDNIL R9 + 0x20240C09, // 0093 NE R9 R6 R9 + 0x78260006, // 0094 JMPF R9 #009C + 0x60240001, // 0095 GETGBL R9 G1 + 0x60280018, // 0096 GETGBL R10 G24 + 0x582C0074, // 0097 LDCONST R11 K116 + 0x5C300C00, // 0098 MOVE R12 R6 + 0x7C280400, // 0099 CALL R10 2 + 0x7C240200, // 009A CALL R9 1 + 0x80001200, // 009B RET 0 + 0x8C24014A, // 009C GETMET R9 R0 K74 + 0x7C240200, // 009D CALL R9 1 + 0x8C24136B, // 009E GETMET R9 R9 K107 + 0x582C0007, // 009F LDCONST R11 K7 + 0x7C240400, // 00A0 CALL R9 2 + 0x5C201200, // 00A1 MOVE R8 R9 + 0x4C240000, // 00A2 LDNIL R9 + 0x20241009, // 00A3 NE R9 R8 R9 + 0x7826000C, // 00A4 JMPF R9 #00B2 + 0x60240010, // 00A5 GETGBL R9 G16 + 0x8C28033C, // 00A6 GETMET R10 R1 K60 + 0x7C280200, // 00A7 CALL R10 1 + 0x7C240200, // 00A8 CALL R9 1 + 0xA8020004, // 00A9 EXBLK 0 #00AF + 0x5C281200, // 00AA MOVE R10 R9 + 0x7C280000, // 00AB CALL R10 0 + 0x942C020A, // 00AC GETIDX R11 R1 R10 + 0x9020140B, // 00AD SETMBR R8 R10 R11 + 0x7001FFFA, // 00AE JMP #00AA + 0x5824003E, // 00AF LDCONST R9 K62 + 0xAC240200, // 00B0 CATCH R9 1 0 + 0xB0080000, // 00B1 RAISE 2 R0 R0 + 0x4C240000, // 00B2 LDNIL R9 + 0x20241009, // 00B3 NE R9 R8 R9 + 0x78260001, // 00B4 JMPF R9 #00B7 + 0x8C241175, // 00B5 GETMET R9 R8 K117 + 0x7C240200, // 00B6 CALL R9 1 + 0x4C240000, // 00B7 LDNIL R9 + 0x60280008, // 00B8 GETGBL R10 G8 + 0x8C2C0340, // 00B9 GETMET R11 R1 K64 + 0x58340076, // 00BA LDCONST R13 K118 + 0x7C2C0400, // 00BB CALL R11 2 + 0x7C280200, // 00BC CALL R10 1 + 0x202C1577, // 00BD NE R11 R10 K119 + 0x782E0012, // 00BE JMPF R11 #00D2 + 0xA8020005, // 00BF EXBLK 0 #00C6 + 0x602C000D, // 00C0 GETGBL R11 G13 + 0x5C301400, // 00C1 MOVE R12 R10 + 0x7C2C0200, // 00C2 CALL R11 1 + 0x5C241600, // 00C3 MOVE R9 R11 + 0xA8040001, // 00C4 EXBLK 1 1 + 0x7002000B, // 00C5 JMP #00D2 + 0xAC2C0002, // 00C6 CATCH R11 0 2 + 0x70020008, // 00C7 JMP #00D1 + 0x60340001, // 00C8 GETGBL R13 G1 + 0x60380018, // 00C9 GETGBL R14 G24 + 0x583C0078, // 00CA LDCONST R15 K120 + 0x5C401400, // 00CB MOVE R16 R10 + 0x5C441600, // 00CC MOVE R17 R11 + 0x5C481800, // 00CD MOVE R18 R12 + 0x7C380800, // 00CE CALL R14 4 + 0x7C340200, // 00CF CALL R13 1 + 0x70020000, // 00D0 JMP #00D2 + 0xB0080000, // 00D1 RAISE 2 R0 R0 + 0x4C2C0000, // 00D2 LDNIL R11 + 0x202C120B, // 00D3 NE R11 R9 R11 + 0x782E0018, // 00D4 JMPF R11 #00EE + 0xA802000B, // 00D5 EXBLK 0 #00E2 + 0x5C2C1200, // 00D6 MOVE R11 R9 + 0x7C2C0000, // 00D7 CALL R11 0 + 0x60300004, // 00D8 GETGBL R12 G4 + 0x5C341600, // 00D9 MOVE R13 R11 + 0x7C300200, // 00DA CALL R12 1 + 0x1C301979, // 00DB EQ R12 R12 K121 + 0x78320002, // 00DC JMPF R12 #00E0 + 0x5C301600, // 00DD MOVE R12 R11 + 0x5C341000, // 00DE MOVE R13 R8 + 0x7C300200, // 00DF CALL R12 1 + 0xA8040001, // 00E0 EXBLK 1 1 + 0x7002000B, // 00E1 JMP #00EE + 0xAC2C0002, // 00E2 CATCH R11 0 2 + 0x70020008, // 00E3 JMP #00ED + 0x60340001, // 00E4 GETGBL R13 G1 + 0x60380018, // 00E5 GETGBL R14 G24 + 0x583C007A, // 00E6 LDCONST R15 K122 + 0x5C401400, // 00E7 MOVE R16 R10 + 0x5C441600, // 00E8 MOVE R17 R11 + 0x5C481800, // 00E9 MOVE R18 R12 + 0x7C380800, // 00EA CALL R14 4 + 0x7C340200, // 00EB CALL R13 1 + 0x70020000, // 00EC JMP #00EE + 0xB0080000, // 00ED RAISE 2 R0 R0 + 0x80000000, // 00EE RET 0 }) ) ); @@ -12207,11 +12311,11 @@ be_local_closure(class_HASPmota_do_action, /* name */ /******************************************************************** -** Solidified function: _load +** Solidified function: parse ********************************************************************/ -be_local_closure(class_HASPmota__load, /* name */ +be_local_closure(class_HASPmota_parse, /* name */ be_nested_proto( - 14, /* nstack */ + 9, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -12220,108 +12324,30 @@ be_local_closure(class_HASPmota__load, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(_load), + be_str_weak(parse), &be_const_str_solidified, - ( &(const binstruction[99]) { /* code */ - 0xA40AD800, // 0000 IMPORT R2 K108 - 0xA40E8200, // 0001 IMPORT R3 K65 - 0x60100011, // 0002 GETGBL R4 G17 - 0x5C140200, // 0003 MOVE R5 R1 - 0x5818006D, // 0004 LDCONST R6 K109 - 0x7C100400, // 0005 CALL R4 2 - 0x8C14096E, // 0006 GETMET R5 R4 K110 - 0x7C140200, // 0007 CALL R5 1 - 0x8C18096F, // 0008 GETMET R6 R4 K111 - 0x7C180200, // 0009 CALL R6 1 - 0x8C180570, // 000A GETMET R6 R2 K112 - 0x5C200A00, // 000B MOVE R8 R5 - 0x58240071, // 000C LDCONST R9 K113 - 0x7C180600, // 000D CALL R6 3 - 0x4C100000, // 000E LDNIL R4 - 0x4C140000, // 000F LDNIL R5 - 0x601C000C, // 0010 GETGBL R7 G12 - 0x5C200C00, // 0011 MOVE R8 R6 - 0x7C1C0200, // 0012 CALL R7 1 - 0x241C0F0A, // 0013 GT R7 R7 K10 - 0x781E0039, // 0014 JMPF R7 #004F - 0x8C1C0742, // 0015 GETMET R7 R3 K66 - 0x94240D0A, // 0016 GETIDX R9 R6 K10 - 0x7C1C0400, // 0017 CALL R7 2 - 0x60200004, // 0018 GETGBL R8 G4 - 0x5C240E00, // 0019 MOVE R9 R7 - 0x7C200200, // 001A CALL R8 1 - 0x1C20113A, // 001B EQ R8 R8 K58 - 0x7822001B, // 001C JMPF R8 #0039 - 0xB822E400, // 001D GETNGBL R8 K114 - 0x8C201173, // 001E GETMET R8 R8 K115 - 0x542A0003, // 001F LDINT R10 4 - 0x7C200400, // 0020 CALL R8 2 - 0x78220007, // 0021 JMPF R8 #002A - 0xB822E400, // 0022 GETNGBL R8 K114 - 0x8C201174, // 0023 GETMET R8 R8 K116 - 0x60280018, // 0024 GETGBL R10 G24 - 0x582C0075, // 0025 LDCONST R11 K117 - 0x94300D0A, // 0026 GETIDX R12 R6 K10 - 0x7C280400, // 0027 CALL R10 2 - 0x542E0003, // 0028 LDINT R11 4 - 0x7C200600, // 0029 CALL R8 3 - 0x8C200143, // 002A GETMET R8 R0 K67 - 0x5C280E00, // 002B MOVE R10 R7 - 0x7C200400, // 002C CALL R8 2 - 0x88200105, // 002D GETMBR R8 R0 K5 - 0x4C240000, // 002E LDNIL R9 - 0x1C201009, // 002F EQ R8 R8 R9 - 0x78220000, // 0030 JMPF R8 #0032 - 0xB0068B76, // 0031 RAISE 1 K69 K118 - 0x8C200144, // 0032 GETMET R8 R0 K68 - 0x5C280E00, // 0033 MOVE R10 R7 - 0x882C0105, // 0034 GETMBR R11 R0 K5 - 0x88300103, // 0035 GETMBR R12 R0 K3 - 0x942C160C, // 0036 GETIDX R11 R11 R12 - 0x7C200600, // 0037 CALL R8 3 - 0x70020010, // 0038 JMP #004A - 0x6020000C, // 0039 GETGBL R8 G12 - 0x8C240577, // 003A GETMET R9 R2 K119 - 0x942C0D0A, // 003B GETIDX R11 R6 K10 - 0x58300078, // 003C LDCONST R12 K120 - 0x58340079, // 003D LDCONST R13 K121 - 0x7C240800, // 003E CALL R9 4 - 0x7C200200, // 003F CALL R8 1 - 0x2420110A, // 0040 GT R8 R8 K10 - 0x78220007, // 0041 JMPF R8 #004A - 0xB822E400, // 0042 GETNGBL R8 K114 - 0x8C201174, // 0043 GETMET R8 R8 K116 - 0x60280018, // 0044 GETGBL R10 G24 - 0x582C007A, // 0045 LDCONST R11 K122 - 0x94300D0A, // 0046 GETIDX R12 R6 K10 - 0x7C280400, // 0047 CALL R10 2 - 0x582C0069, // 0048 LDCONST R11 K105 - 0x7C200600, // 0049 CALL R8 3 - 0x4C1C0000, // 004A LDNIL R7 - 0x8C200D2F, // 004B GETMET R8 R6 K47 - 0x5828000A, // 004C LDCONST R10 K10 - 0x7C200400, // 004D CALL R8 2 - 0x7001FFC0, // 004E JMP #0010 - 0x4C180000, // 004F LDNIL R6 - 0x8C1C0110, // 0050 GETMET R7 R0 K16 - 0x4C240000, // 0051 LDNIL R9 - 0x7C1C0400, // 0052 CALL R7 2 - 0x6020000C, // 0053 GETGBL R8 G12 - 0x5C240E00, // 0054 MOVE R9 R7 - 0x7C200200, // 0055 CALL R8 1 - 0x1C20110A, // 0056 EQ R8 R8 K10 - 0x78220000, // 0057 JMPF R8 #0059 - 0xB0068B7B, // 0058 RAISE 1 K69 K123 - 0x94200F0A, // 0059 GETIDX R8 R7 K10 - 0x90020808, // 005A SETMBR R0 K4 R8 - 0x88200105, // 005B GETMBR R8 R0 K5 - 0x88240104, // 005C GETMBR R9 R0 K4 - 0x94201009, // 005D GETIDX R8 R8 R9 - 0x8C201115, // 005E GETMET R8 R8 K21 - 0x5828000A, // 005F LDCONST R10 K10 - 0x582C000A, // 0060 LDCONST R11 K10 - 0x7C200600, // 0061 CALL R8 3 - 0x80000000, // 0062 RET 0 + ( &(const binstruction[21]) { /* code */ + 0xA40A2C00, // 0000 IMPORT R2 K22 + 0x8C0C051C, // 0001 GETMET R3 R2 K28 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x60100004, // 0004 GETGBL R4 G4 + 0x5C140600, // 0005 MOVE R5 R3 + 0x7C100200, // 0006 CALL R4 1 + 0x1C10091D, // 0007 EQ R4 R4 K29 + 0x78120009, // 0008 JMPF R4 #0013 + 0x8C100122, // 0009 GETMET R4 R0 K34 + 0x5C180600, // 000A MOVE R6 R3 + 0x7C100400, // 000B CALL R4 2 + 0x8C100125, // 000C GETMET R4 R0 K37 + 0x5C180600, // 000D MOVE R6 R3 + 0x881C010C, // 000E GETMBR R7 R0 K12 + 0x88200102, // 000F GETMBR R8 R0 K2 + 0x941C0E08, // 0010 GETIDX R7 R7 R8 + 0x7C100600, // 0011 CALL R4 3 + 0x70020000, // 0012 JMP #0014 + 0xB006477B, // 0013 RAISE 1 K35 K123 + 0x80000000, // 0014 RET 0 }) ) ); @@ -12329,52 +12355,53 @@ be_local_closure(class_HASPmota__load, /* name */ /******************************************************************** -** Solidified function: sort +** Solidified function: get_pages ********************************************************************/ -be_local_closure(class_HASPmota_sort, /* name */ +be_local_closure(class_HASPmota_get_pages, /* name */ be_nested_proto( - 7, /* nstack */ + 4, /* nstack */ 1, /* argc */ - 12, /* varg */ + 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_HASPmota, /* shared constants */ - be_str_weak(sort), + be_str_weak(get_pages), &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x5804003C, // 0000 LDCONST R1 K60 - 0x60080010, // 0001 GETGBL R2 G16 - 0x600C000C, // 0002 GETGBL R3 G12 - 0x5C100000, // 0003 MOVE R4 R0 - 0x7C0C0200, // 0004 CALL R3 1 - 0x040C0711, // 0005 SUB R3 R3 K17 - 0x400E2203, // 0006 CONNECT R3 K17 R3 - 0x7C080200, // 0007 CALL R2 1 - 0xA8020010, // 0008 EXBLK 0 #001A - 0x5C0C0400, // 0009 MOVE R3 R2 - 0x7C0C0000, // 000A CALL R3 0 - 0x94100003, // 000B GETIDX R4 R0 R3 - 0x5C140600, // 000C MOVE R5 R3 - 0x24180B0A, // 000D GT R6 R5 K10 - 0x781A0008, // 000E JMPF R6 #0018 - 0x04180B11, // 000F SUB R6 R5 K17 - 0x94180006, // 0010 GETIDX R6 R0 R6 - 0x24180C04, // 0011 GT R6 R6 R4 - 0x781A0004, // 0012 JMPF R6 #0018 - 0x04180B11, // 0013 SUB R6 R5 K17 - 0x94180006, // 0014 GETIDX R6 R0 R6 - 0x98000A06, // 0015 SETIDX R0 R5 R6 - 0x04140B11, // 0016 SUB R5 R5 K17 - 0x7001FFF4, // 0017 JMP #000D - 0x98000A04, // 0018 SETIDX R0 R5 R4 - 0x7001FFEE, // 0019 JMP #0009 - 0x58080027, // 001A LDCONST R2 K39 - 0xAC080200, // 001B CATCH R2 1 0 - 0xB0080000, // 001C RAISE 2 R0 R0 - 0x80040000, // 001D RET 1 R0 + ( &(const binstruction[ 4]) { /* code */ + 0x8C040101, // 0000 GETMET R1 R0 K1 + 0x4C0C0000, // 0001 LDNIL R3 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_page_cur +********************************************************************/ +be_local_closure(class_HASPmota_get_page_cur, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_HASPmota, /* shared constants */ + be_str_weak(get_page_cur), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8804010C, // 0000 GETMBR R1 R0 K12 + 0x88080102, // 0001 GETMBR R2 R0 K2 + 0x94040202, // 0002 GETIDX R1 R1 R2 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -12387,67 +12414,68 @@ be_local_closure(class_HASPmota_sort, /* name */ be_local_class(HASPmota, 11, NULL, - be_nested_map(59, + be_nested_map(60, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(lvh_dropdown_list, 50), be_const_class(be_class_lvh_dropdown_list) }, - { be_const_key_weak(lvh_line, 19), be_const_class(be_class_lvh_line) }, - { be_const_key_weak(r16, -1), be_const_var(4) }, - { be_const_key_weak(page_show, -1), be_const_closure(class_HASPmota_page_show_closure) }, - { be_const_key_weak(parse_page, -1), be_const_closure(class_HASPmota_parse_page_closure) }, - { be_const_key_weak(sort, 12), be_const_static_closure(class_HASPmota_sort_closure) }, - { be_const_key_weak(event_dispatch, -1), be_const_closure(class_HASPmota_event_dispatch_closure) }, - { be_const_key_weak(lvh_roller, 10), be_const_class(be_class_lvh_roller) }, - { be_const_key_weak(lvh_page_cur_idx_parsing, -1), be_const_var(7) }, - { be_const_key_weak(hres, -1), be_const_var(1) }, - { be_const_key_weak(lvh_page_cur_idx, -1), be_const_var(6) }, - { be_const_key_weak(_remove_page, 13), be_const_closure(class_HASPmota__remove_page_closure) }, - { be_const_key_weak(lvh_chart, -1), be_const_class(be_class_lvh_chart) }, - { be_const_key_weak(_load, 16), be_const_closure(class_HASPmota__load_closure) }, - { be_const_key_weak(dark, 5), be_const_var(0) }, - { be_const_key_weak(parse_obj, 6), be_const_closure(class_HASPmota_parse_obj_closure) }, - { be_const_key_weak(lvh_msgbox, -1), be_const_class(be_class_lvh_msgbox) }, - { be_const_key_weak(get_page_cur, 29), be_const_closure(class_HASPmota_get_page_cur_closure) }, - { be_const_key_weak(event, -1), be_const_var(9) }, - { be_const_key_weak(scr, 51), be_const_var(3) }, - { be_const_key_weak(vres, -1), be_const_var(2) }, - { be_const_key_weak(lvh_scale, -1), be_const_class(be_class_lvh_scale) }, - { be_const_key_weak(register_event, 24), be_const_closure(class_HASPmota_register_event_closure) }, - { be_const_key_weak(lvh_arc, -1), be_const_class(be_class_lvh_arc) }, - { be_const_key_weak(do_action, 23), be_const_closure(class_HASPmota_do_action_closure) }, - { be_const_key_weak(lvh_dropdown, -1), be_const_class(be_class_lvh_dropdown) }, - { be_const_key_weak(lvh_fixed, -1), be_const_class(be_class_lvh_fixed) }, - { be_const_key_weak(re_page_target, 43), be_const_var(8) }, - { be_const_key_weak(lvh_slider, -1), be_const_class(be_class_lvh_slider) }, - { be_const_key_weak(fix_lv_version, -1), be_const_static_closure(class_HASPmota_fix_lv_version_closure) }, - { be_const_key_weak(lvh_checkbox, -1), be_const_class(be_class_lvh_checkbox) }, - { be_const_key_weak(parse, 47), be_const_closure(class_HASPmota_parse_closure) }, - { be_const_key_weak(lvh_pages, -1), be_const_var(5) }, - { be_const_key_weak(lvh_btn, -1), be_const_class(be_class_lvh_btn) }, - { be_const_key_weak(start, -1), be_const_closure(class_HASPmota_start_closure) }, - { be_const_key_weak(lvh_root, -1), be_const_class(be_class_lvh_root) }, - { be_const_key_weak(lvh_page, -1), be_const_class(be_class_lvh_page) }, - { be_const_key_weak(pages_list_sorted, 26), be_const_closure(class_HASPmota_pages_list_sorted_closure) }, - { be_const_key_weak(lvh_qrcode, 45), be_const_class(be_class_lvh_qrcode) }, - { be_const_key_weak(lvh_label, -1), be_const_class(be_class_lvh_label) }, - { be_const_key_weak(lvh_scr, 28), be_const_class(be_class_lvh_scr) }, - { be_const_key_weak(lvh_img, 27), be_const_class(be_class_lvh_img) }, - { be_const_key_weak(get_page_cur_parsing, 30), be_const_closure(class_HASPmota_get_page_cur_parsing_closure) }, - { be_const_key_weak(page_dir_to, 49), be_const_closure(class_HASPmota_page_dir_to_closure) }, - { be_const_key_weak(lvh_obj, -1), be_const_class(be_class_lvh_obj) }, - { be_const_key_weak(lvh_switch, -1), be_const_class(be_class_lvh_switch) }, - { be_const_key_weak(lvh_bar, -1), be_const_class(be_class_lvh_bar) }, - { be_const_key_weak(init, -1), be_const_closure(class_HASPmota_init_closure) }, - { be_const_key_weak(lvh_btnmatrix, -1), be_const_class(be_class_lvh_btnmatrix) }, - { be_const_key_weak(lvh_spinner, 52), be_const_class(be_class_lvh_spinner) }, - { be_const_key_weak(lvh_led, 3), be_const_class(be_class_lvh_led) }, - { be_const_key_weak(lvh_flex, 57), be_const_class(be_class_lvh_flex) }, { be_const_key_weak(lvh_spangroup, -1), be_const_class(be_class_lvh_spangroup) }, - { be_const_key_weak(lvh_span, -1), be_const_class(be_class_lvh_span) }, - { be_const_key_weak(def_templ_name, 9), be_nested_str_weak(pages_X2Ejsonl) }, - { be_const_key_weak(lvh_scale_section, 7), be_const_class(be_class_lvh_scale_section) }, - { be_const_key_weak(event_cb, -1), be_const_var(10) }, - { be_const_key_weak(lvh_scale_line, -1), be_const_class(be_class_lvh_scale_line) }, + { be_const_key_weak(lvh_switch, -1), be_const_class(be_class_lvh_switch) }, + { be_const_key_weak(lvh_scr, -1), be_const_class(be_class_lvh_scr) }, + { be_const_key_weak(register_event, 55), be_const_closure(class_HASPmota_register_event_closure) }, + { be_const_key_weak(lvh_line, -1), be_const_class(be_class_lvh_line) }, + { be_const_key_weak(dark, 0), be_const_var(0) }, + { be_const_key_weak(_load, -1), be_const_closure(class_HASPmota__load_closure) }, { be_const_key_weak(lvh_cpicker, -1), be_const_class(be_class_lvh_cpicker) }, + { be_const_key_weak(lvh_page_cur_idx, -1), be_const_var(6) }, + { be_const_key_weak(lvh_page, 54), be_const_class(be_class_lvh_page) }, + { be_const_key_weak(event_dispatch, -1), be_const_closure(class_HASPmota_event_dispatch_closure) }, + { be_const_key_weak(scr, 28), be_const_var(3) }, + { be_const_key_weak(fix_lv_version, 22), be_const_static_closure(class_HASPmota_fix_lv_version_closure) }, + { be_const_key_weak(get_page_cur_parsing, -1), be_const_closure(class_HASPmota_get_page_cur_parsing_closure) }, + { be_const_key_weak(lvh_btn, -1), be_const_class(be_class_lvh_btn) }, + { be_const_key_weak(init, -1), be_const_closure(class_HASPmota_init_closure) }, + { be_const_key_weak(lvh_scale_section, -1), be_const_class(be_class_lvh_scale_section) }, + { be_const_key_weak(lvh_msgbox, -1), be_const_class(be_class_lvh_msgbox) }, + { be_const_key_weak(get_page_cur, -1), be_const_closure(class_HASPmota_get_page_cur_closure) }, + { be_const_key_weak(get_pages, -1), be_const_closure(class_HASPmota_get_pages_closure) }, + { be_const_key_weak(lvh_chart, -1), be_const_class(be_class_lvh_chart) }, + { be_const_key_weak(sort, -1), be_const_static_closure(class_HASPmota_sort_closure) }, + { be_const_key_weak(lvh_fixed, 17), be_const_class(be_class_lvh_fixed) }, + { be_const_key_weak(r16, -1), be_const_var(4) }, + { be_const_key_weak(lvh_scale, 19), be_const_class(be_class_lvh_scale) }, + { be_const_key_weak(parse_obj, -1), be_const_closure(class_HASPmota_parse_obj_closure) }, + { be_const_key_weak(def_templ_name, -1), be_nested_str_weak(pages_X2Ejsonl) }, + { be_const_key_weak(lvh_dropdown, 53), be_const_class(be_class_lvh_dropdown) }, + { be_const_key_weak(start, -1), be_const_closure(class_HASPmota_start_closure) }, + { be_const_key_weak(lvh_obj, -1), be_const_class(be_class_lvh_obj) }, + { be_const_key_weak(lvh_root, 41), be_const_class(be_class_lvh_root) }, + { be_const_key_weak(lvh_arc, -1), be_const_class(be_class_lvh_arc) }, + { be_const_key_weak(lvh_bar, 44), be_const_class(be_class_lvh_bar) }, + { be_const_key_weak(lvh_img, -1), be_const_class(be_class_lvh_img) }, + { be_const_key_weak(_remove_page, -1), be_const_closure(class_HASPmota__remove_page_closure) }, + { be_const_key_weak(lvh_btnmatrix, 48), be_const_class(be_class_lvh_btnmatrix) }, + { be_const_key_weak(pages_list_sorted, 45), be_const_closure(class_HASPmota_pages_list_sorted_closure) }, + { be_const_key_weak(lvh_led, -1), be_const_class(be_class_lvh_led) }, + { be_const_key_weak(parse_page, 18), be_const_closure(class_HASPmota_parse_page_closure) }, + { be_const_key_weak(lvh_spinner, 32), be_const_class(be_class_lvh_spinner) }, + { be_const_key_weak(lvh_span, 23), be_const_class(be_class_lvh_span) }, + { be_const_key_weak(re_page_target, 40), be_const_var(8) }, + { be_const_key_weak(page_dir_to, 20), be_const_closure(class_HASPmota_page_dir_to_closure) }, + { be_const_key_weak(lvh_scale_line, 37), be_const_class(be_class_lvh_scale_line) }, + { be_const_key_weak(event, -1), be_const_var(9) }, + { be_const_key_weak(lvh_qrcode, 47), be_const_class(be_class_lvh_qrcode) }, + { be_const_key_weak(lvh_pages, 31), be_const_var(5) }, + { be_const_key_weak(lvh_dropdown_list, 34), be_const_class(be_class_lvh_dropdown_list) }, + { be_const_key_weak(do_action, 29), be_const_closure(class_HASPmota_do_action_closure) }, + { be_const_key_weak(vres, 26), be_const_var(2) }, + { be_const_key_weak(lvh_roller, 25), be_const_class(be_class_lvh_roller) }, + { be_const_key_weak(lvh_slider, -1), be_const_class(be_class_lvh_slider) }, + { be_const_key_weak(parse, -1), be_const_closure(class_HASPmota_parse_closure) }, + { be_const_key_weak(hres, -1), be_const_var(1) }, + { be_const_key_weak(lvh_flex, -1), be_const_class(be_class_lvh_flex) }, + { be_const_key_weak(lvh_page_cur_idx_parsing, -1), be_const_var(7) }, + { be_const_key_weak(lvh_label, -1), be_const_class(be_class_lvh_label) }, + { be_const_key_weak(event_cb, 7), be_const_var(10) }, + { be_const_key_weak(page_show, 1), be_const_closure(class_HASPmota_page_show_closure) }, + { be_const_key_weak(lvh_checkbox, -1), be_const_class(be_class_lvh_checkbox) }, })), be_str_weak(HASPmota) ); From 16a145f8095ac3a2d6d13372ea055730cc4c5573 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:39:36 +0200 Subject: [PATCH 038/205] Fix ESP32(C3) DALI transmit stability by disabling interrupts --- CHANGELOG.md | 4 +- RELEASENOTES.md | 3 +- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 40 ++++++++++++++------ 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b83c987bd..f75f2a0f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,8 +13,8 @@ All notable changes to this project will be documented in this file. - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC (#22347) - SolaxX1 Meter mode (#22330) - DALI inverted signal configuration using GPIO DALI RX_i/TX_i -- Experimental support for Shelly DALI Dimmer Gen3 (See template in file xdrv_75_dali.ino) -- HASPmota `haspmota.get_pages()` to get the sorted list of pages +- Support for Shelly DALI Dimmer Gen3 (See tips and template in file xdrv_75_dali.ino) +- HASPmota `haspmota.get_pages()` to get the sorted list of pages (#22358) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e22ff627e..e67ab7d3b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -121,12 +121,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliGroup` to add gear to groups - DALI command `DaliTarget` to set light control broadcast, group number or gear number - DALI inverted signal configuration using GPIO DALI RX_i/TX_i -- Experimental support for Shelly DALI Dimmer Gen3 (See template in file xdrv_75_dali.ino) +- Support for Shelly DALI Dimmer Gen3 (See tips and template in file xdrv_75_dali.ino) - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) +- HASPmota `haspmota.get_pages()` to get the sorted list of pages [#22358](https://github.com/arendst/Tasmota/issues/22358) ### Breaking Changed diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index 887e279ab..e553dd594 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -19,6 +19,8 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 1.0.0.2 20241025 update - Fix GPIO detection + - Fix ESP32(C3) transmit stability by disabling interrupts 1.0.0.1 20241024 update - Change from signal invert defines to GPIO config DALI RX_i/DALI TX_i - Fix inverted DALI signal support - Experimental support for Shelly DALI Dimmer Gen3 @@ -67,11 +69,11 @@ * DaliSend <0xA3>,,, - Set DALI parameter using DTR0 and do not expect a DALI backward frame * DaliQuery , - Execute DALI code and report result (DALI backward frame) * DaliScan 1|2 - Reset (0) or (1)/and commission device short addresses - * DaliGear 1..64 - Set max short address to speed up scanning - default is 64 + * DaliGear 1..64 - Set max short address to speed up scanning - default 64 * DaliGroup<1..16> [+]|-,... - Add(+) or Remove(-) devices to/from group * DaliPower|| 0..254 - Control power (0 = Off, 1 = Last dimmer, 2 = Toggle, 3..254 = absolute light brightness) * DaliDimmer|| 0..100 - Control dimmer (0 = Off, 1..100 = precentage of brightness) - * DaliLight 0|1 - Enable Tasmota light control for DaliTarget device + * DaliLight 0|1 - Enable Tasmota light control for DaliTarget device - default 1 * DaliTarget || - Set Tasmota light control device (0, 1..64, 101..116) - default 0 * * DALI background information @@ -83,10 +85,10 @@ * Special command 101CCCC1 to 110CCCC1 * A = Address bit, S = 0 Direct Arc Power control, S = 1 Command, C = Special command * - * Shelly DALI Dimmer Gen3 (ESP32C3-8M) - * Template {"NAME":"Shelly DALI Dimmer Gen3","GPIO":[34,4736,1,3840,11360,11392,128,129,1,1,576,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1} + * Shelly DALI Dimmer Gen3 (ESP32C3-8M) - GPIO3 controls DALI power. In following template it is always ON. Max output is 16V/10mA (= 5 DALI gear) + * Template {"NAME":"Shelly DALI Dimmer Gen3","GPIO":[34,4736,0,3840,11360,11392,128,129,0,1,576,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1} * AdcGpio1 10000,10000,4000 <- Temperature parameters - * Backlog ButtonTopic 0; SetOption1 1; SetOption11 0; SetOption32 20 + * Backlog ButtonTopic 0; SetOption1 1; SetOption11 0; SetOption32 20; DimmerStep 5; LedTable 0 * rule1 on button1#state=2 do dimmer + endon on button2#state=2 do dimmer - endon on button1#state=3 do power 2 endon on button2#state=3 do power 2 endon \*********************************************************************************************/ @@ -449,8 +451,14 @@ void DaliSendDataOnce(uint16_t send_dali_data) { bool dali_read; bool collision = false; uint32_t bit_pos = 15; - uint32_t wait = ESP.getCycleCount(); uint32_t bit_number = 0; + +#ifdef ESP32 + {portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL(&mux); +#endif + + uint32_t wait = ESP.getCycleCount(); while (bit_number < 35) { // 417 * 35 = 14.7 ms if (!collision) { if (0 == (bit_number &1)) { // Even bit @@ -482,6 +490,11 @@ void DaliSendDataOnce(uint16_t send_dali_data) { bit_number++; } + +#ifdef ESP32 + portEXIT_CRITICAL(&mux);} +#endif + // delayMicroseconds(1100); // Adds to total 15.8 ms Dali->last_activity = millis(); } @@ -516,7 +529,7 @@ void DaliSendData(uint32_t adr, uint32_t cmd) { } #ifdef DALI_DEBUG - AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: SendData Repeat %d, Adr 0x%02X, Cmd 0x%02x"), repeat, adr, cmd); + AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Tx 0x%d%02X%02X"), repeat, adr, cmd); #endif // DALI_DEBUG uint16_t send_dali_data = adr << 8 | cmd; @@ -547,7 +560,7 @@ int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout) { Dali->response = false; #ifdef DALI_DEBUG - AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: SendWaitResponse result %d = 0x%04X"), result, result); + AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Rx 0x%05X"), result); #endif // DALI_DEBUG return result; @@ -603,8 +616,9 @@ uint32_t DaliGearPresent(void) { } void DaliInitLight(void) { - // Taken from Shelly Dali Dimmer ;-) Settings->light_fade = 0; // Use Dali fading + Settings->light_correction = 0; // Use Dali light correction + // Taken from Shelly Dali Dimmer ;-) DaliSendData(DALI_DATA_TRANSFER_REGISTER0, DALI_INIT_FADE); // Fade x second DaliSendData(0xFF, DALI_SET_FADE_TIME); DaliSendData(DALI_DATA_TRANSFER_REGISTER0, 0); // Power off after gear power restore @@ -830,6 +844,7 @@ void DaliEverySecond(void) { bool DaliSetChannels(void) { if (Settings->sbflag1.dali_light) { // DaliLight 1 Settings->light_fade = 0; // Use Dali fading + Settings->light_correction = 0; // Use Dali light correction if (Dali->light_sync) { // Block local loop Dali->light_sync = false; } else { @@ -848,7 +863,7 @@ bool DaliInit(void) { Dali = (DALI*)calloc(sizeof(DALI), 1); if (!Dali) { return false; } - Dali->pin_tx = -1; + Dali->pin_tx = 255; if (PinUsed(GPIO_DALI_TX)) { Dali->pin_tx = Pin(GPIO_DALI_TX); } @@ -856,7 +871,7 @@ bool DaliInit(void) { Dali->pin_tx = Pin(GPIO_DALI_TX_INV); Dali->invert_tx = true; } - Dali->pin_rx = -1; + Dali->pin_rx = 255; if (PinUsed(GPIO_DALI_RX)) { Dali->pin_rx = Pin(GPIO_DALI_RX); } @@ -864,7 +879,7 @@ bool DaliInit(void) { Dali->pin_rx = Pin(GPIO_DALI_RX_INV); Dali->invert_rx = true; } - if ((-1 == Dali->pin_tx) || (-1 == Dali->pin_rx)) { + if ((255 == Dali->pin_tx) || (255 == Dali->pin_rx)) { free(Dali); return false; } @@ -893,6 +908,7 @@ bool DaliInit(void) { } Settings->light_fade = 0; // Use Dali fading instead + Settings->light_correction = 0; // Use Dali light correction UpdateDevicesPresent(1); TasmotaGlobal.light_type = LT_SERIAL1; // Single channel return true; From 73cd5cee25002f60368c2166dd1ebaa7e9a06a25 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:44:42 +0200 Subject: [PATCH 039/205] Add support for US AQI and EPA AQI in PMS5003x sensors (#22294) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/include/i18n.h | 4 +- .../tasmota_xsns_sensor/xsns_18_pms5003.ino | 82 ++++++++++++++++++- 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f75f2a0f0..0337f1a19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file. - DALI inverted signal configuration using GPIO DALI RX_i/TX_i - Support for Shelly DALI Dimmer Gen3 (See tips and template in file xdrv_75_dali.ino) - HASPmota `haspmota.get_pages()` to get the sorted list of pages (#22358) +- Support for US AQI and EPA AQI in PMS5003x sensors (#22294) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e67ab7d3b..5562fe537 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -122,6 +122,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliTarget` to set light control broadcast, group number or gear number - DALI inverted signal configuration using GPIO DALI RX_i/TX_i - Support for Shelly DALI Dimmer Gen3 (See tips and template in file xdrv_75_dali.ino) +- Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h index 5555ec9d9..b243f01e4 100644 --- a/tasmota/include/i18n.h +++ b/tasmota/include/i18n.h @@ -1006,7 +1006,9 @@ const char HTTP_SNS_STANDARD_CONCENTRATION[] PROGMEM = "{s}%s " D_STANDAR const char HTTP_SNS_ENVIRONMENTAL_CONCENTRATION[] PROGMEM = "{s}%s " D_ENVIRONMENTAL_CONCENTRATION " %s " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"; const char HTTP_SNS_F_ENVIRONMENTAL_CONCENTRATION[] PROGMEM = "{s}%s " D_ENVIRONMENTAL_CONCENTRATION " %s " D_UNIT_MICROMETER "{m}%1_f " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"; const char HTTP_SNS_PARTICALS_BEYOND[] PROGMEM = "{s}%s " D_PARTICALS_BEYOND " %s " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"; -const char HTTP_SNS_AVG_RAD_DOSE[] PROGMEM = "{s}%s " D_AVG_RAD_DOSE " %s " D_UNIT_MINUTE "{m}%d.%02d " D_UNIT_US_H "{e}"; +const char HTTP_SNS_AVG_RAD_DOSE[] PROGMEM = "{s}%s " D_AVG_RAD_DOSE " %s " D_UNIT_MINUTE "{m}%d.%02d " D_UNIT_US_H "{e}"; +const char HTTP_SNS_US_AQI[] PROGMEM = "{s}%s US AQI" "{m}%d" "{e}"; +const char HTTP_SNS_US_EPA_AQI[] PROGMEM = "{s}%s US EPA AQI" "{m}%d" "{e}"; const char HTTP_SNS_VOLTAGE[] PROGMEM = "{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"; const char HTTP_SNS_CURRENT[] PROGMEM = "{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"; diff --git a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino index a5f9e0ced..1da6a0058 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino @@ -353,6 +353,59 @@ void PmsInit(void) { } } +// This gives more accurate data for forest fire smoke. PurpleAir gives you this conversion option labeled "US EPA" +// https://cfpub.epa.gov/si/si_public_record_report.cfm?dirEntryId=353088&Lab=CEMM +/* +Copy-paste from the PDF Slide 26 +y={0 ≤ x <30: 0.524*x - 0.0862*RH + 5.75} +y={30≤ x <50: (0.786*(x/20 - 3/2) + 0.524*(1 - (x/20 - 3/2)))*x -0.0862*RH + 5.75} +y={50 ≤ x <210: 0.786*x - 0.0862*RH + 5.75} +y={210 ≤ x <260: (0.69*(x/50 – 21/5) + 0.786*(1 - (x/50 – 21/5)))*x - 0.0862*RH*(1 - (x/50 – 21/5)) + 2.966*(x/50 – 21/5) + 5.75*(1 - (x/50 – 21/5)) + 8.84*(10^{-4})*x^{2}*(x/50 – 21/5)} +y={260 ≤ x: 2.966 + 0.69*x + 8.84*10^{-4}*x^2} + +y= corrected PM2.5 µg/m3 +x= PM2.5 cf_atm (lower) +RH= Relative humidity as measured by the PurpleAir +*/ +int usaEpaStandardPm2d5Adjustment(int pm25_standard, int relative_humidity) +{ + // Rename to use the same variables from the paper + float x = pm25_standard; + float RH = relative_humidity; + if (x<30) { + return 0.524f * x - 0.0862f * RH + 5.75f; + } else if(x<50) { + return (0.786f * (x/20.0f - 3.0f/2.0f) + 0.524f * (1.0f - (x/20.0f - 3.0f/2.0f))) * x - 0.0862f * RH + 5.75f; + } else if(x<210) { + return 0.786f * x - 0.0862f * RH + 5.75f; + } else if(x<260) { + return (0.69f * (x/50.0f - 21.0f/5.0f) + 0.786f * (1.0f - (x/50.0f - 21.0f/5.0f))) * x - 0.0862f * RH * (1.0f - (x/50.0f - 21.0f/5.0f)) + 2.966f * (x/50.0f - 21.0f/5.0f) + 5.75f * (1.0f - (x/50.0f - 21.0f/5.0f)) + 8.84f * FastPrecisePowf(10.0f, -4.0f) * FastPrecisePowf(x,2.0f) * (x/50.0f - 21.0f/5.0f); + } else { + return 2.966f + 0.69f * x + 8.84f * FastPrecisePowf(10.0f, -4.0f) * FastPrecisePowf(x, 2.0f); + } +} + +// Compute US AQI using the 2024+ table +// https://forum.airnowtech.org/t/the-aqi-equation-2024-valid-beginning-may-6th-2024/453 +int compute_us_aqi(int pm25_standard) +{ + if (pm25_standard <= 9) { + return map_double(pm25_standard, 0, 9, 0, 50); + } else if (pm25_standard <= 35) { + return map_double(pm25_standard, 9.1f, 35.4f, 51, 100); + } else if (pm25_standard <= 55) { + return map_double(pm25_standard, 35.5f, 55.4f, 101, 150); + } else if (pm25_standard <= 125) { + return map_double(pm25_standard, 55.5f, 125.4f, 151, 200); + } else if (pm25_standard <= 225) { + return map_double(pm25_standard, 125.5f, 225.4f, 201, 300); + } else if (pm25_standard <= 325) { + return map_double(pm25_standard, 225.5f, 325.4f, 301, 500); + } else { + return 500; + } +} + void PmsShow(bool json) { if (Pms.valid) { char types[10]; @@ -370,20 +423,37 @@ void PmsShow(bool json) { #ifdef PMS_MODEL_PMS5003T float temperature = ConvertTemp(pms_data.temperature10x/10.0); float humidity = ConvertHumidity(pms_data.humidity10x/10.0); + int epa_us_aqi; + // When in Fahrenheit include US AQI + if (Settings->flag.temperature_conversion) { // Fahrenheit - US, Liberia, Cayman Islands + epa_us_aqi = compute_us_aqi(usaEpaStandardPm2d5Adjustment(pms_data.pm25_standard, humidity)); + } #endif // PMS_MODEL_PMS5003T + int us_aqi; + // Use US AQI for Fahrenheit, EAQI (European Air Quality Index) for Celsius + if (Settings->flag.temperature_conversion) { // Fahrenheit - US, Liberia, Cayman Islands + us_aqi = compute_us_aqi(pms_data.pm25_standard); + } if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d"), types, pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard, pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env); + if (Settings->flag.temperature_conversion) { // Fahrenheit - US, Liberia, Cayman Islands + ResponseAppend_P(PSTR(",\"US_AQI\":%d"), us_aqi); + } #if !(defined(PMS_MODEL_PMS3003) || defined(PMS_MODEL_ZH03X)) - ResponseAppend_P(PSTR(",\"PB0.3\":%d,\"PB0.5\":%d,\"PB1\":%d,\"PB2.5\":%d,"), + ResponseAppend_P(PSTR(",\"PB0.3\":%d,\"PB0.5\":%d,\"PB1\":%d,\"PB2.5\":%d"), pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um); #ifdef PMS_MODEL_PMS5003T + ResponseAppend_P(PSTR(",")); ResponseAppendTHD(temperature, humidity); + if (Settings->flag.temperature_conversion) { // Fahrenheit - US, Liberia, Cayman Islands + ResponseAppend_P(PSTR(",\"US_EPA_AQI\":%d"), epa_us_aqi); + } #else - ResponseAppend_P(PSTR("\"PB5\":%d,\"PB10\":%d"), + ResponseAppend_P(PSTR(",\"PB5\":%d,\"PB10\":%d"), pms_data.particles_50um, pms_data.particles_100um); #endif // PMS_MODEL_PMS5003T #endif // No PMS_MODEL_PMS3003 @@ -409,8 +479,14 @@ void PmsShow(bool json) { WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "0.5", pms_data.particles_05um); WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "1", pms_data.particles_10um); WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "2.5", pms_data.particles_25um); + if (Settings->flag.temperature_conversion) { // Fahrenheit - US, Liberia, Cayman Islands + WSContentSend_PD(HTTP_SNS_US_AQI, types, us_aqi); + } #ifdef PMS_MODEL_PMS5003T WSContentSend_THD(types, temperature, humidity); + if (Settings->flag.temperature_conversion) { // Fahrenheit - US, Liberia, Cayman Islands + WSContentSend_PD(HTTP_SNS_US_EPA_AQI, types, epa_us_aqi); + } #else WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "5", pms_data.particles_50um); WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "10", pms_data.particles_100um); @@ -455,4 +531,4 @@ bool Xsns18(uint32_t function) return result; } -#endif // USE_PMS5003 +#endif // USE_PMS5003 \ No newline at end of file From 33e1da84e7c7fa63b3569e865d04cffbcdfb1e39 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Fri, 25 Oct 2024 17:45:26 +0300 Subject: [PATCH 040/205] Xsns 102 ld2410 (#21880) * xsns_102_ld2410.ino add commands * fix * Add attension about supported devices * Fix lang files --- tasmota/include/tasmota_types.h | 2 +- tasmota/language/af_AF.h | 12 +- tasmota/language/bg_BG.h | 12 +- tasmota/language/ca_AD.h | 12 +- tasmota/language/cs_CZ.h | 12 +- tasmota/language/de_DE.h | 12 +- tasmota/language/el_GR.h | 12 +- tasmota/language/en_GB.h | 12 +- tasmota/language/es_ES.h | 12 +- tasmota/language/fr_FR.h | 12 +- tasmota/language/fy_NL.h | 12 +- tasmota/language/he_HE.h | 12 +- tasmota/language/hu_HU.h | 12 +- tasmota/language/it_IT.h | 12 +- tasmota/language/ko_KO.h | 12 +- tasmota/language/nl_NL.h | 12 +- tasmota/language/pl_PL.h | 12 +- tasmota/language/pt_BR.h | 12 +- tasmota/language/pt_PT.h | 12 +- tasmota/language/ro_RO.h | 12 +- tasmota/language/ru_RU.h | 12 +- tasmota/language/sk_SK.h | 12 +- tasmota/language/sv_SE.h | 12 +- tasmota/language/tr_TR.h | 12 +- tasmota/language/uk_UA.h | 12 +- tasmota/language/vi_VN.h | 12 +- tasmota/language/zh_CN.h | 12 +- tasmota/language/zh_TW.h | 12 +- tasmota/my_user_config.h | 2 +- .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 140 +++++++++++++++--- 30 files changed, 364 insertions(+), 104 deletions(-) mode change 100755 => 100644 tasmota/include/tasmota_types.h diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h old mode 100755 new mode 100644 index 241f8c249..3ad75c19a --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -194,7 +194,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t neopool_outputsensitive : 1; // bit 11 (v13.2.0.1) - SetOption157 - (NeoPool) Output sensitive data (1) uint32_t mqtt_disable_modbus : 1; // bit 12 (v13.3.0.5) - SetOption158 - (MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead uint32_t counter_both_edges : 1; // bit 13 (v13.3.0.5) - SetOption159 - (Counter) Enable counting on both rising and falling edge (1) - uint32_t spare14 : 1; // bit 14 + uint32_t ld2410_use_pin : 1; // bit 14 (development) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1) uint32_t spare15 : 1; // bit 15 uint32_t spare16 : 1; // bit 16 uint32_t spare17 : 1; // bit 17 diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 0c55d7f18..833b69109 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -87,9 +87,6 @@ #define D_DEBUG "Ontfout" #define D_DEWPOINT "Dou punt" #define D_DISABLED "Gedeaktiveer" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Afstand" #define D_DNS_SERVER "DNS" #define D_DO "Opgeloste suurstof" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 78ba90ca2..c9d21ebbf 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -87,9 +87,6 @@ #define D_DEBUG "Премахване на дефекти" #define D_DEWPOINT "Температура на оросяване" #define D_DISABLED "Забранено" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Разстояние" #define D_DNS_SERVER "Сървър на DNS" #define D_DO "Разтворен кислород" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index 894362945..b1b4e3774 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -87,9 +87,6 @@ #define D_DEBUG "Depuració" #define D_DEWPOINT "Punt de rossada" #define D_DISABLED "Deshabilitat" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distancia" #define D_DNS_SERVER "Servidor DNS" #define D_DO "Oxígen dissolt" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 4df9b761b..34f4960a5 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Zablokováno" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distance" #define D_DNS_SERVER "Server DNS" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 77f0f5bd3..4dd0ef06b 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -87,9 +87,6 @@ #define D_DEBUG "debug" #define D_DEWPOINT "Taupunkt" #define D_DISABLED "deaktiviert" -#define D_MOVING_DISTANCE "Abstand bewegt" -#define D_STATIC_DISTANCE "Abstand fix" -#define D_DETECT_DISTANCE "Abstandsfeststellung" #define D_DISTANCE "Abstand" #define D_DNS_SERVER "DNS-Server" #define D_DO "gelöster Sauerstoff" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Abstand bewegt" +#define D_STATIC_DISTANCE "Abstand fix" +#define D_DETECT_DISTANCE "Abstandsfeststellung" +#define D_MOVING_ENERGY_T "Bewegliches Ziel" +#define D_STATIC_ENERGY_T "Statisches Ziel" +#define D_LD2410_PIN_STATE "Zustand des Ausgangspins" +#define D_LD2410_LIGHT "Lichtsensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 4915b82ff..8bee01c59 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Ανενεργό" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Απόσταση" #define D_DNS_SERVER "Διακομιστής DNS" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index edd3370dd..89b97304f 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Disabled" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distance" #define D_DNS_SERVER "DNS Server" #define D_DO "Disolved Oxygen" @@ -1282,6 +1279,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 77eb3c295..12573a7ea 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Punto de Rocío" #define D_DISABLED "Deshabilitado" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distancia" #define D_DNS_SERVER "Servidor DNS" #define D_DO "Oxígeno Disuelto" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 41dd53979..ff797e535 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Point de rosée" #define D_DISABLED "Désactivé" -#define D_MOVING_DISTANCE "Distance mobile" -#define D_STATIC_DISTANCE "Distance fixe" -#define D_DETECT_DISTANCE "Distance détectée" #define D_DISTANCE "Distance" #define D_DNS_SERVER "Serveur DNS" #define D_DO "Oxygène dissout" @@ -1282,6 +1279,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Distance mobile" +#define D_STATIC_DISTANCE "Distance fixe" +#define D_DETECT_DISTANCE "Distance détectée" +#define D_MOVING_ENERGY_T "Cible mouvante" +#define D_STATIC_ENERGY_T "Cible statique" +#define D_LD2410_PIN_STATE "État de la broche de sortie" +#define D_LD2410_LIGHT "Capteur de lumière" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 2fe8b6eec..f453906c1 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debugearje" #define D_DEWPOINT "Dauwpunt" #define D_DISABLED "Útsetten" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Ôfstân" #define D_DNS_SERVER "DNS Server" #define D_DO "Oploste soerstof" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 97615d7b7..0470168d6 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -87,9 +87,6 @@ #define D_DEBUG "באגים" #define D_DEWPOINT "Dew point" #define D_DISABLED "מבוטל" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "מרחק" #define D_DNS_SERVER "DNS שרת" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index e9370b023..7d3360d5e 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Harmatpont" #define D_DISABLED "Letiltva" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Távolság" #define D_DNS_SERVER "DNS szerver" #define D_DO "Oldott oxygén" @@ -1284,6 +1281,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 56ceb08af..b4db89599 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Punto rugiada" // #define D_DISABLED "Disabilitato/a" -#define D_MOVING_DISTANCE "Distanza in movimento" -#define D_STATIC_DISTANCE "Distanza statica" -#define D_DETECT_DISTANCE "Rileva distanza" #define D_DISTANCE "Distanza" #define D_DNS_SERVER "Server DNS" #define D_DO "Ossigeno dissolto" @@ -1282,6 +1279,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar - TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar - RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Distanza in movimento" +#define D_STATIC_DISTANCE "Distanza statica" +#define D_DETECT_DISTANCE "Rileva distanza" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Target statico" +#define D_LD2410_PIN_STATE "Stato pin di uscita" +#define D_LD2410_LIGHT "Sensore di luce" + // xsns_115_wooliis.ino #define D_IMPORT "Importa" #define D_EXPORT "Esporta" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index a4208da31..04fea6e29 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -87,9 +87,6 @@ #define D_DEBUG "디버그" #define D_DEWPOINT "Dew point" #define D_DISABLED "사용안함" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "거리" #define D_DNS_SERVER "DNS 서버" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 6e0a38287..e7485142d 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dauwpunt" #define D_DISABLED "Uitgeschakeld" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Afstand" #define D_DNS_SERVER "DNS Server" #define D_DO "Opgelost zuurstof" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 56d95235d..ad6a7f7a3 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Punkt rosy" #define D_DISABLED "Wyłączony" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Odległość" #define D_DNS_SERVER "Serwer DNS" #define D_DO "Rozpuszczalność tlenu" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 5d21edca2..aa24ef463 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -87,9 +87,6 @@ #define D_DEBUG "Depurar" #define D_DEWPOINT "Ponto de orvalho" #define D_DISABLED "Desabilitado" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distância" #define D_DNS_SERVER "Servidor DNS" #define D_DO "Oxigênio dissolvido" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 3108fd24c..36a229459 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -87,9 +87,6 @@ #define D_DEBUG "Depurar" #define D_DEWPOINT "Ponto de Condensação" #define D_DISABLED "Disabilitado" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distância" #define D_DNS_SERVER "Servidor DNS" #define D_DO "Oxigénio Dissolvido" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index eb5042cad..77c696942 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -87,9 +87,6 @@ #define D_DEBUG "Depanare" #define D_DEWPOINT "Punct de rouă" #define D_DISABLED "Dezactivat" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distanță" #define D_DNS_SERVER "Server DNS" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index a6180994a..3092ba52a 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -88,9 +88,6 @@ #define D_DEBUG "Отладка" #define D_DEWPOINT "Dew point" #define D_DISABLED "Блокирован" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Расстояние" #define D_DNS_SERVER "DNS Сервер" #define D_DO "Disolved Oxygen" @@ -1282,6 +1279,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 2affb9750..3eadc6ece 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -89,9 +89,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Zablokované" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Vzdialenosť" #define D_DNS_SERVER "Server DNS" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 486d4939a..a75f9051e 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -87,9 +87,6 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Inaktiverad" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distans" #define D_DNS_SERVER "DNS-server" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 2da473200..aefb8dd9d 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -87,9 +87,6 @@ #define D_DEBUG "Hata Ayıklama" #define D_DEWPOINT "Dew point" #define D_DISABLED "Etkin Değil" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Mesage" #define D_DNS_SERVER "DNS Sunucu" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index bb2210680..e3fe0db29 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -87,9 +87,6 @@ #define D_DEBUG "Налагодження" #define D_DEWPOINT "Tочка роси" #define D_DISABLED "Вимкнено" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Відстань" #define D_DNS_SERVER "Сервер DNS" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index ef176f815..335c7a370 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -87,9 +87,6 @@ #define D_DEBUG "Tìm lỗi" #define D_DEWPOINT "Điểm sương" #define D_DISABLED "Vô hiệu hóa" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Khoảng cách" #define D_DNS_SERVER "Máy chủ DNS" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index a11e94e57..05474720f 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -87,9 +87,6 @@ #define D_DEBUG "调试" #define D_DEWPOINT "Dew point" #define D_DISABLED "禁用" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "距离" #define D_DNS_SERVER "DNS服务器" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index b2c08d951..8cb743922 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -87,9 +87,6 @@ #define D_DEBUG "偵錯" #define D_DEWPOINT "Dew point" #define D_DISABLED "已停用" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "距離" #define D_DNS_SERVER "DNS伺服器" #define D_DO "Disolved Oxygen" @@ -1281,6 +1278,15 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e9d8128bb..c7955d636 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -880,7 +880,7 @@ //#define USE_VINDRIKTNING // Add support for IKEA VINDRIKTNING particle concentration sensor (+0k6 code) // #define VINDRIKTNING_SHOW_PM1 // Display undocumented/supposed PM1.0 values // #define VINDRIKTNING_SHOW_PM10 // Display undocumented/supposed PM10 values -//#define USE_LD2410 // Add support for HLK-LD2410 24GHz smart wave motion sensor (+2k8 code) +//#define USE_LD2410 // Add support for HLK-LD2410 24GHz smart wave motion sensor (+3k7 code) //#define USE_LOX_O2 // Add support for LuminOx LOX O2 Sensor (+0k8 code) //#define USE_GM861 // Add support for GM861 1D and 2D Bar Code Reader (+1k3 code) // #define GM861_DECODE_AIM // Decode AIM-id (+0k3 code) diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino index 8d80d3199..50dcb846e 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -1,7 +1,7 @@ /* xsns_102_ld2410.ino - HLK-LD2410 24GHz smart wave motion sensor support for Tasmota - SPDX-FileCopyrightText: 2022 Theo Arends + SPDX-FileCopyrightText: 2022 Theo Arends, 2024 md5sum-as (https://github.com/md5sum-as) SPDX-License-Identifier: GPL-3.0-only */ @@ -9,12 +9,21 @@ #ifdef USE_LD2410 /*********************************************************************************************\ * HLK-LD2410 24GHz smart wave motion sensor - * + * + * Attention! + * This module works with HLK-LD2410, HLK-LD2410B (md5sum-as tested), HLK-LD2410C (md5sum-as tested) devices. + * The module does not support HLK-LD2410S (md5sum-as tested) and is not guaranteed to work with other devices. + * + * * LD2410Duration 0 - Set factory default settings * LD2410Duration 1..65535 - Set no-one duration in seconds (default 5) * LD2410MovingSens 50,50,40,30,20,15,15,15,15 - Set moving distance sensitivity for up to 9 gates (at 0.75 meter interval) * LD2410StaticSens 0,0,40,40,30,30,20,20,20 - Set static distance sensitivity for up to 9 gates (at 0.75 meter interval) * + * LD2410Get - Read last sensors + * LD2410EngineeringStart - Start engineering mode + * LD2410EngineeringEnd - End engineering mode + * * Inspiration: * https://community.home-assistant.io/t/mmwave-wars-one-sensor-module-to-rule-them-all/453260/2 * Resources: @@ -69,6 +78,14 @@ struct { uint8_t settings; uint8_t byte_counter; bool valid_response; + uint8_t set_engin_mode; + uint8_t web_engin_mode; + struct { + uint8_t moving_gate_energy[LD2410_MAX_GATES +1]; + uint8_t static_gate_energy[LD2410_MAX_GATES +1]; + uint8_t light; + uint8_t out_pin; + } engineering; } LD2410; /********************************************************************************************/ @@ -80,7 +97,10 @@ uint32_t ToBcd(uint32_t value) { /********************************************************************************************/ void Ld1410HandleTargetData(void) { - if ((0x0D == LD2410.buffer[4]) && (0x55 == LD2410.buffer[17])) { // Add bad reception detection + uint8_t i; + + if (((0x0D == LD2410.buffer[4]) && (0x55 == LD2410.buffer[17]) && (0x02 == LD2410.buffer[6])) + or ((0x23 == LD2410.buffer[4]) && (0x55 == LD2410.buffer[39]) && (0x01 == LD2410.buffer[6]))) { // Add bad reception detection // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // F4 F3 F2 F1 0D 00 02 AA 00 00 00 00 00 00 37 00 00 55 00 F8 F7 F6 F5 - No target // F4 F3 F2 F1 0D 00 02 AA 00 45 00 3E 00 00 3A 00 00 55 00 F8 F7 F6 F5 - No target @@ -88,30 +108,55 @@ void Ld1410HandleTargetData(void) { // F4 F3 F2 F1 0D 00 02 AA 02 54 00 00 00 00 64 00 00 55 00 F8 F7 F6 F5 - Stationary target // F4 F3 F2 F1 0D 00 02 AA 02 96 00 00 00 00 36 00 00 55 00 F8 F7 F6 F5 - Stationary target // F4 F3 F2 F1 0D 00 02 AA 03 2A 00 64 00 00 64 00 00 55 00 F8 F7 F6 F5 - Movement and Stationary target + // + // 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 35 36 37 38 39 40 41 42 43 44 + // F4 F3 F2 F1 23 00 01 AA 00 1E 00 00 1E 00 0D 00 00 08 08 13 0E 07 02 05 07 03 04 05 00 00 0D 06 05 05 05 05 05 62 00 55 00 F8 F7 F6 F5 + // + // F4 F3 F2 F1 23 00 01 AA 02 20 01 00 37 01 64 26 01 + // 08 08 - max moving and static dist (17,18) + // 12 05 04 09 0C 0D 0F 04 01 - Movement energy (19-27) + // 00 00 1F 64 64 64 64 31 1A - Static energy (28-36) + // 8C - Photo sens (37) + // 01 - Out pin (38) + // 55 00 F8 F7 F6 F5 // header |len |dt|hd|st|movin|me|stati|se|detec|tr|ck|trailer + + LD2410.moving_distance = 0; + LD2410.moving_energy = 0; + LD2410.static_distance = 0; + LD2410.static_energy = 0; + LD2410.detect_distance = 0; + if (LD2410.buffer[8] != 0x00) { // Movement and/or Stationary target LD2410.moving_distance = LD2410.buffer[10] << 8 | LD2410.buffer[9]; LD2410.moving_energy = LD2410.buffer[11]; LD2410.static_distance = LD2410.buffer[13] << 8 | LD2410.buffer[12]; LD2410.static_energy = LD2410.buffer[14]; LD2410.detect_distance = LD2410.buffer[16] << 8 | LD2410.buffer[15]; - /* - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Type %d, State %d, Moving %d/%d%%, Static %d/%d%%, Detect %d"), - LD2410.buffer[6], LD2410.buffer[8], - LD2410.moving_distance, LD2410.moving_energy, - LD2410.static_distance, LD2410.static_energy, - LD2410.detect_distance); - */ - if (0x01 == LD2410.buffer[6]) { // Engineering mode data - // Adds 22 extra bytes of data + } + LD2410.web_engin_mode = LD2410.buffer[6]==1?1:0; + if (0x01 == LD2410.buffer[6]) { /* Engineering mode*/ + if (LD2410.buffer[17] < 9) { + for (i=0; i<= LD2410.buffer[17]; i++) { + LD2410.engineering.moving_gate_energy[i] = LD2410.buffer[i+19]; + } } - } else { - LD2410.moving_distance = 0; - LD2410.moving_energy = 0; - LD2410.static_distance = 0; - LD2410.static_energy = 0; - LD2410.detect_distance = 0; + if (LD2410.buffer[18] < 9) { + for (i=0; i<= LD2410.buffer[18]; i++) { + LD2410.engineering.static_gate_energy[i] = LD2410.buffer[i+28]; + } + } + LD2410.engineering.light=LD2410.buffer[37]; + LD2410.engineering.out_pin=LD2410.buffer[38]; + // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2 Eng: mov: %d %d %d %d %d %d %d %d %d, st: %d %d %d %d %d %d %d %d %d, light: %d, out: %d"), + // LD2410.engineering.moving_gate_energy[0],LD2410.engineering.moving_gate_energy[1],LD2410.engineering.moving_gate_energy[2], + // LD2410.engineering.moving_gate_energy[3],LD2410.engineering.moving_gate_energy[4],LD2410.engineering.moving_gate_energy[5], + // LD2410.engineering.moving_gate_energy[6],LD2410.engineering.moving_gate_energy[7],LD2410.engineering.moving_gate_energy[8], + // LD2410.engineering.static_gate_energy[0],LD2410.engineering.static_gate_energy[1],LD2410.engineering.static_gate_energy[2], + // LD2410.engineering.static_gate_energy[3],LD2410.engineering.static_gate_energy[4],LD2410.engineering.static_gate_energy[5], + // LD2410.engineering.static_gate_energy[6],LD2410.engineering.static_gate_energy[7],LD2410.engineering.static_gate_energy[8], + // LD2410.engineering.light,LD2410.engineering.out_pin); } } } @@ -355,6 +400,18 @@ void Ld2410Every100MSecond(void) { LD2410Serial->begin(57600); break; */ + case 17: + Ld2410SetConfigMode(); // Stop running mode + break; + case 14: + if (0 == LD2410.set_engin_mode) { + Ld2410SendCommand(LD2410_CMND_END_ENGINEERING); + } else { + Ld2410SendCommand(LD2410_CMND_START_ENGINEERING); + } + LD2410.step = 2; + break; + // case 12: Init case 5: Ld2410SetConfigMode(); // Stop running mode @@ -393,7 +450,8 @@ void Ld2410Every100MSecond(void) { } void Ld2410EverySecond(void) { - if (LD2410.moving_energy) { + if (LD2410.moving_energy and (!Settings->flag6.ld2410_use_pin)) { + // Send state change to be captured by rules // {"Time":"2022-11-26T10:48:16","Switch1":"ON","LD2410":{"Distance":[125.0,0.0,0.0],"Energy":[0,100]}} MqttPublishSensor(); @@ -414,6 +472,8 @@ void Ld2410Detect(void) { LD2410.retry = 4; LD2410.step = 12; } + LD2410.set_engin_mode = 0; + memset(&LD2410.engineering,0,sizeof(LD2410.engineering)); } } @@ -422,10 +482,10 @@ void Ld2410Detect(void) { \*********************************************************************************************/ const char kLd2410Commands[] PROGMEM = "LD2410|" // Prefix - "Duration|MovingSens|StaticSens"; + "Duration|MovingSens|StaticSens|Get|EngineeringEnd|EngineeringStart"; void (* const Ld2410Command[])(void) PROGMEM = { - &CmndLd2410Duration, &CmndLd2410MovingSensitivity, &CmndLd2410StaticSensitivity }; + &CmndLd2410Duration, &CmndLd2410MovingSensitivity, &CmndLd2410StaticSensitivity, &CmndLd2410last, &CmndLd2410EngineeringEnd, &CmndLd2410EngineeringStart }; void Ld2410Response(void) { Response_P(PSTR("{\"LD2410\":{\"Duration\":%d,\"Moving\":{\"Gates\":%d,\"Sensitivity\":["), @@ -483,6 +543,29 @@ void CmndLd2410StaticSensitivity(void) { Ld2410Response(); } +void CmndLd2410last(void) { + Response_P(PSTR("{\"LD2410\":{\"Moving energy\":[%d,%d,%d,%d,%d,%d,%d,%d,%d],\"Static energy\":[%d,%d,%d,%d,%d,%d,%d,%d,%d],\"Light\":%d,\"Out_pin\":%d}}"), + LD2410.engineering.moving_gate_energy[0],LD2410.engineering.moving_gate_energy[1],LD2410.engineering.moving_gate_energy[2], + LD2410.engineering.moving_gate_energy[3],LD2410.engineering.moving_gate_energy[4],LD2410.engineering.moving_gate_energy[5], + LD2410.engineering.moving_gate_energy[6],LD2410.engineering.moving_gate_energy[7],LD2410.engineering.moving_gate_energy[8], + LD2410.engineering.static_gate_energy[0],LD2410.engineering.static_gate_energy[1],LD2410.engineering.static_gate_energy[2], + LD2410.engineering.static_gate_energy[3],LD2410.engineering.static_gate_energy[4],LD2410.engineering.static_gate_energy[5], + LD2410.engineering.static_gate_energy[6],LD2410.engineering.static_gate_energy[7],LD2410.engineering.static_gate_energy[8], + LD2410.engineering.light,LD2410.engineering.out_pin); +} + +void CmndLd2410EngineeringEnd(void) { + LD2410.set_engin_mode = 0; + LD2410.step = 18; + Response_P(PSTR("LD2410: End engineering mode")); +} + +void CmndLd2410EngineeringStart(void) { + LD2410.set_engin_mode= 1; + LD2410.step = 18; + Response_P(PSTR("LD2410: Start engineering mode")); +} + /*********************************************************************************************\ * Presentation \*********************************************************************************************/ @@ -492,6 +575,11 @@ const char HTTP_SNS_LD2410_CM[] PROGMEM = "{s}LD2410 " D_MOVING_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}" "{s}LD2410 " D_STATIC_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}" "{s}LD2410 " D_DETECT_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}"; +const char HTTP_SNS_LD2410_ENG[] PROGMEM = + "{s}LD2410 " D_MOVING_ENERGY_T "{m}%d %d %d %d %d %d %d %d %d{e}" + "{s}LD2410 " D_STATIC_ENERGY_T "{m}%d %d %d %d %d %d %d %d %d{e}" + "{s}LD2410 " D_LD2410_LIGHT "{m}%d{e}" + "{s}LD2410 " D_LD2410_PIN_STATE "{m}%d{e}"; #endif void Ld2410Show(bool json) { @@ -505,6 +593,16 @@ void Ld2410Show(bool json) { #ifdef USE_WEBSERVER } else { WSContentSend_PD(HTTP_SNS_LD2410_CM, &moving_distance, &static_distance, &detect_distance); + if (LD2410.web_engin_mode == 1) { + WSContentSend_PD(HTTP_SNS_LD2410_ENG, + LD2410.engineering.moving_gate_energy[0],LD2410.engineering.moving_gate_energy[1],LD2410.engineering.moving_gate_energy[2], + LD2410.engineering.moving_gate_energy[3],LD2410.engineering.moving_gate_energy[4],LD2410.engineering.moving_gate_energy[5], + LD2410.engineering.moving_gate_energy[6],LD2410.engineering.moving_gate_energy[7],LD2410.engineering.moving_gate_energy[8], + LD2410.engineering.static_gate_energy[0],LD2410.engineering.static_gate_energy[1],LD2410.engineering.static_gate_energy[2], + LD2410.engineering.static_gate_energy[3],LD2410.engineering.static_gate_energy[4],LD2410.engineering.static_gate_energy[5], + LD2410.engineering.static_gate_energy[6],LD2410.engineering.static_gate_energy[7],LD2410.engineering.static_gate_energy[8], + LD2410.engineering.light,LD2410.engineering.out_pin); + } #endif } } From 41442a54cecd9e6936708e28a0ad254b5a1f3b6e Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Fri, 25 Oct 2024 18:09:05 +0300 Subject: [PATCH 041/205] add xsns_102_ld2410s.ino (#22253) Co-authored-by: Theo Arends <11044339+arendst@users.noreply.github.com> --- tasmota/include/tasmota_template.h | 6 + tasmota/language/af_AF.h | 2 + tasmota/language/bg_BG.h | 2 + tasmota/language/ca_AD.h | 2 + tasmota/language/cs_CZ.h | 2 + tasmota/language/de_DE.h | 2 + tasmota/language/el_GR.h | 2 + tasmota/language/en_GB.h | 2 + tasmota/language/es_ES.h | 2 + tasmota/language/fr_FR.h | 2 + tasmota/language/fy_NL.h | 2 + tasmota/language/he_HE.h | 2 + tasmota/language/hu_HU.h | 2 + tasmota/language/it_IT.h | 2 + tasmota/language/ko_KO.h | 2 + tasmota/language/nl_NL.h | 2 + tasmota/language/pl_PL.h | 2 + tasmota/language/pt_BR.h | 2 + tasmota/language/pt_PT.h | 2 + tasmota/language/ro_RO.h | 2 + tasmota/language/ru_RU.h | 2 + tasmota/language/sk_SK.h | 2 + tasmota/language/sv_SE.h | 2 + tasmota/language/tr_TR.h | 2 + tasmota/language/uk_UA.h | 2 + tasmota/language/vi_VN.h | 2 + tasmota/language/zh_CN.h | 2 + tasmota/language/zh_TW.h | 2 + tasmota/my_user_config.h | 1 + .../tasmota_xsns_sensor/xsns_102_ld2410s.ino | 743 ++++++++++++++++++ 30 files changed, 804 insertions(+) create mode 100644 tasmota/tasmota_xsns_sensor/xsns_102_ld2410s.ino diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 053df5677..5c694d28e 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -225,6 +225,7 @@ enum UserSelectablePins { GPIO_ADC_VOLTAGE, GPIO_ADC_CURRENT, // Analog Voltage and Current GPIO_BL0906_RX, // BL0906 Serial interface GPIO_DALI_RX_INV, GPIO_DALI_TX_INV, // DALI + GPIO_LD2410S_TX, GPIO_LD2410S_RX, // HLK-LD2410S GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage with max 2045 @@ -497,6 +498,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_ADC_VOLTAGE "|" D_SENSOR_ADC_CURRENT "|" D_SENSOR_BL0906_RX "|" D_SENSOR_DALI_RX "_i|" D_SENSOR_DALI_TX "_i|" + D_SENSOR_LD2410S_TX "|" D_SENSOR_LD2410S_RX "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -1104,6 +1106,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_LD2410_TX), // HLK-LD2410 Serial interface AGPIO(GPIO_LD2410_RX), // HLK-LD2410 Serial interface #endif +#ifdef USE_LD2410S // xsns_102_ld2410s.ino + AGPIO(GPIO_LD2410S_TX), // HLK-LD2410S Serial interface + AGPIO(GPIO_LD2410S_RX), // HLK-LD2410S Serial interface +#endif #ifdef USE_LOX_O2 // xsns_105_lox_o2.ino AGPIO(GPIO_LOX_O2_RX), // LuminOx Oxygen Sensor LOX-O2 Serial interface #endif diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 833b69109..49fcb7f03 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index c9d21ebbf..00b556988 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index b1b4e3774..c8234cd9f 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 34f4960a5..3e58a9142 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 4dd0ef06b..b0ad57474 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 8bee01c59..d06e9ed8c 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 89b97304f..f27ecacd3 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 12573a7ea..2e0f81424 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index ff797e535..19f1088bc 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 Wr" #define D_GPIO_TM1621_RD "TM1621 Rd" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index f453906c1..68f0d7962 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 0470168d6..f56920cff 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 7d3360d5e..51fd05c23 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index b4db89599..f756f44b7 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 - RX" #define D_SENSOR_LD2410_TX "LD2410 - TX" #define D_SENSOR_LD2410_RX "LD2410 - RX" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 - CS" #define D_GPIO_TM1621_WR "TM1621 - WR" #define D_GPIO_TM1621_RD "TM1621 - RD" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 04fea6e29..54a986b06 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index e7485142d..8f2f340d1 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index ad6a7f7a3..c7d595703 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index aa24ef463..daa039322 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 36a229459..74b9fc7a6 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 77c696942..62b2e2c53 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 3092ba52a..04abb790a 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -775,6 +775,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 3eadc6ece..b5cce5b26 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index a75f9051e..f03dc4165 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index aefb8dd9d..b790992a9 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index e3fe0db29..fbaa81d83 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 335c7a370..ea7214335 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 05474720f..0d36a5de1 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 8cb743922..5d86c6fa4 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -774,6 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 Rx" #define D_SENSOR_LD2410_TX "LD2410 Tx" #define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index c7955d636..1a7766d8e 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -881,6 +881,7 @@ // #define VINDRIKTNING_SHOW_PM1 // Display undocumented/supposed PM1.0 values // #define VINDRIKTNING_SHOW_PM10 // Display undocumented/supposed PM10 values //#define USE_LD2410 // Add support for HLK-LD2410 24GHz smart wave motion sensor (+3k7 code) +//#define USE_LD2410S // Add support for HLK-LD2410S 24GHz smart wave motion sensor (+4k6 code) //#define USE_LOX_O2 // Add support for LuminOx LOX O2 Sensor (+0k8 code) //#define USE_GM861 // Add support for GM861 1D and 2D Bar Code Reader (+1k3 code) // #define GM861_DECODE_AIM // Decode AIM-id (+0k3 code) diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410s.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410s.ino new file mode 100644 index 000000000..e66c575cd --- /dev/null +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410s.ino @@ -0,0 +1,743 @@ +/* + xsns_102_ld2410s.ino - HLK-LD2410S 24GHz smart wave motion sensor support for Tasmota + + SPDX-FileCopyrightText: 2022 Theo Arends, 2024 md5sum-as (https://github.com/md5sum-as) + + SPDX-License-Identifier: GPL-3.0-only +*/ + +#ifdef USE_LD2410S + +/*********************************************************************************************\ + * HLK-LD2410S 24GHz smart wave motion sensor + * + * Attention! + * This module works with HLK-LD2410S devices. + * The module does not support another HLK-LD2410 devices. + * + * Available commands: + * LD2410S_Parameters - showing previously received parameters + * LD2410S_ReRead - reread common, trigger and hold parameters from device + * LD2410S_SetCommon 0-16,1-16,10-120,5-80,5-80,5/10 - set common: near door, far door, hold_time, status_freq, distance_freq, response_speed + * LD2410S_SetTrigger n,n1..n16 - set trigger values (16) + * LD2410S_SetHold n,n1..n16 - set hold values (16) + * LD2410S_Out_Mode 0/1 - set device output mode 0-short (only distance and 0/1 - no people, 2/3 detect people), 1-normal mode (add energy values per door) + * LD2410S_AutoUpdate 2,1,60 - start autoupdate trigger and hold thresholds/ Params: trigger_scale,retension_factor,scan_time + * LD2410S_Follow 0/1 - if 1 then start reports every seconds + * +\*********************************************************************************************/ + +#define XSNS_102 102 + +#undef TM_SERIAL_BUFFER_SIZE +#define TM_SERIAL_BUFFER_SIZE 128 +#define LD2410S_BUFFER_SIZE TM_SERIAL_BUFFER_SIZE // 128 + +#define LD2410S_NUM_GATES 16 + +#define LD2410S_CMND_START_CONFIGURATION 0xFF +#define LD2410S_CMND_END_CONFIGURATION 0xFE +#define LD2410S_CMND_SET_COMMON 0x70 +#define LD2410S_CMND_READ_COMMON 0x71 +#define LD2410S_CMND_AUTO_THRESHOLD 0x09 +#define LD2410S_CMND_WRITE_TRIGGER 0x72 +#define LD2410S_CMND_READ_TRIGGER 0x73 +#define LD2410S_CMND_WRITE_HOLD 0x76 +#define LD2410S_CMND_READ_HOLD 0x77 +#define LD2410S_CMND_OUTPUT_MODE 0x7A + +#define CMD_LD2410S_Read_Parametrs 40 +#define CMD_LD2410S_Write_Common 50 +#define CMD_LD2410S_Out_Mode 60 +#define CMD_LD2410S_Auto_Update 100 +#define CMD_LD2410S_Write_Trigger 70 +#define CMD_LD2410S_Write_Hold 65 + +const uint8_t LD2410_config_header[4] = {0xFD, 0xFC, 0xFB, 0xFA}; +const uint8_t LD2410_config_footer[4] = {0x04, 0x03, 0x02, 0x01}; +const uint8_t LD2410_target_header[4] = {0xF4, 0xF3, 0xF2, 0xF1}; +const uint8_t LD2410_target_footer[4] = {0xF8, 0xF7, 0xF6, 0xF5}; + +#include +TasmotaSerial *LD2410Serial = nullptr; + +struct { + uint8_t *buffer; +// Common params + uint8_t far_end; + uint8_t near_end; + uint8_t hold_duration; + uint8_t status_report_f; + uint8_t distance_report_f; + uint8_t response_speed; +// gates param + uint8_t trigger_energy[LD2410S_NUM_GATES]; // not 16 + uint8_t hold_energy[LD2410S_NUM_GATES]; // not 16 +// Report values + uint16_t detect_distance; + uint8_t energy[LD2410S_NUM_GATES]; // not 16 + uint8_t human; + uint8_t human_last; + +// uint8_t state; + uint8_t step; + uint8_t retry; + uint8_t next_step; + uint8_t byte_counter; + uint8_t ack; + uint8_t out_mode; + uint8_t report_type; + uint8_t follow; +// autoupdate + uint8_t auto_upd__scale; + uint8_t auto_upd_retension; + uint8_t auto_upd_time; +} LD2410S; + +/********************************************************************************************/ + +void Ld1410HandleTargetData(void) { + if (LD2410S.step > 150) {LD2410S.step = 20;} //Stop boot delay on receive valid data +/* +F4F3F2F1 - 0..3 +4600 - 4,5 length 70 +01 - 6 type +02 - 7 people +9100 - 8,9 distance +4600 - 10,11 - old dist??? +00000000 - 12..15 0..3 +543D0000 - 16..19 4..7 +1D160000 - 20..23 8..11 +2E070000 D8020000 B0040000 DF000000 FD010000 74040000 B4070000 72090000 F0040000 C8000000 F0040000 A4060000 CE050000 F8F7F6F5 +*/ + if ((LD2410S.buffer[6] == 1) && (LD2410S.buffer[4] == 70)) { + if (LD2410S.report_type == 3) { + Ld2410ExecCommand(CMD_LD2410S_Read_Parametrs); + } + LD2410S.report_type = 1; + LD2410S.detect_distance = LD2410S.buffer[9] << 8 | LD2410S.buffer[8]; + LD2410S.human = LD2410S.buffer[7]; + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + LD2410S.energy[i] = /*LD2410S.buffer[i * 4 + 13] << 8 |*/ LD2410S.buffer[i * 4 + 12]; + } + } + if ((LD2410S.buffer[6]) == 3) { + /* F4F3F2F1 0300 03 6400 F8F7F6F5 + len type percent + */ + LD2410S.report_type = 3; + LD2410S.detect_distance = LD2410S.buffer[7]; + } +} + + + +void Ld1410HandleConfigData(void) { + LD2410S.ack = 0; + if ((LD2410S.buffer[8]==0) && (LD2410S.buffer[7]==1)) { + LD2410S.ack = LD2410S.buffer[6]; + } + if (LD2410S_CMND_READ_COMMON == LD2410S.buffer[6]) { + // FDFCFBFA - header 0,1,2,3 + // 1C00 - datalen 4,5 + // 7101 - command 6,7 + // 0000 - ACK 8,9 + // 00000000 - Near 10,11,12,13 + // 0C000000 - Far 14,15,16,17 + // 0A000000 - Hold 18,19,20,21 + // 28000000 - StatusF 22,23,24,25 + // 05000000 - DistanceF 26,27,28,29 + // 05000000 - RespSpeed 30,31,32,33 + // 04030201 + LD2410S.near_end = LD2410S.buffer[10]; + LD2410S.far_end = LD2410S.buffer[14]; + LD2410S.hold_duration = LD2410S.buffer[18]; + LD2410S.status_report_f = LD2410S.buffer[22]; + LD2410S.distance_report_f = LD2410S.buffer[26]; + LD2410S.response_speed = LD2410S.buffer[30]; + } else if (LD2410S_CMND_READ_TRIGGER == LD2410S.buffer[6]) { + /*FDFCFBFA - 0..3 + 4400 - 4,5 + 7301 - 6,7 + 0000 - 8,9 + 30000000 2A000000 24000000 22000000 20000000 1F000000 1F000000 1F000000 1F000000 1F000000 1F000000 1F000000 1F000000 1F000000 1F000000 1F000000 04030201 + 10 14 20 + */ + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + LD2410S.trigger_energy[i] = /*LD2410S.buffer[i * 4 + 11] << 8 |*/ LD2410S.buffer[i * 4 + 10]; + } + } else if (LD2410S_CMND_READ_HOLD == LD2410S.buffer[6]) { + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + LD2410S.hold_energy[i] = /*LD2410S.buffer[i * 4 + 11] << 8 |*/ LD2410S.buffer[i * 4 + 10]; + } + } +} + +bool Ld2410Match(const uint8_t *header, uint32_t offset) { + for (uint32_t i = 0; i < 4; i++) { + if (LD2410S.buffer[offset +i] != header[i]) { return false; } + } + return true; +} + +bool Ld2410MatchShort(uint32_t offset) { + if (LD2410S.buffer[offset] != 0x6e) { return false; } + if (LD2410S.buffer[offset+1] > 0x03) { return false; } + if (LD2410S.buffer[offset+4] != 0x62) { return false; } + LD2410S.detect_distance=LD2410S.buffer[offset+3] << 8 | LD2410S.buffer[offset+2]; + LD2410S.human = LD2410S.buffer[offset+1]; + if (LD2410S.report_type == 3) { + Ld2410ExecCommand(CMD_LD2410S_Read_Parametrs); + } + LD2410S.report_type = 0; + if (LD2410S.step > 150) {LD2410S.step = 20;} //Stop boot delay on receive valid data + return true; +} + +void Ld2410Input(void) { + while (LD2410Serial->available()) { + yield(); // Fix watchdogs + + LD2410S.buffer[LD2410S.byte_counter++] = LD2410Serial->read(); +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), LD2410.byte_counter, LD2410.buffer); + + if (LD2410S.byte_counter < 5) { continue; } // Need first four header bytes + + uint32_t header_start = LD2410S.byte_counter -5; // Fix interrupted header transmits + bool short_report = (Ld2410MatchShort(header_start)); + if (short_report) { + LD2410S.byte_counter = 0; // Finished + break; // Exit loop to satisfy yields + } + bool target_header = (Ld2410Match(LD2410_target_header, header_start)); // F4F3F2F1 + bool config_header = (Ld2410Match(LD2410_config_header, header_start)); // FDFCFBFA + if ((target_header || config_header) && (header_start != 0)) { + memmove(LD2410S.buffer, LD2410S.buffer + header_start, 5); // Sync buffer with header + LD2410S.byte_counter = 5; + } + if (LD2410S.byte_counter < 6) { continue; } // Need packet size bytes + + target_header = (Ld2410Match(LD2410_target_header, 0)); // F4F3F2F1 + config_header = (Ld2410Match(LD2410_config_header, 0)); // FDFCFBFA + if (target_header || config_header) { + uint32_t len = LD2410S.buffer[4] +10; // Total packet size + if (len > LD2410S_BUFFER_SIZE) { + LD2410S.byte_counter = 0; // Invalid data + break; // Exit loop to satisfy yields + } + if (LD2410S.byte_counter < len) { continue; } // Need complete packet + if (target_header) { // F4F3F2F1 + if (Ld2410Match(LD2410_target_footer, len -4)) { // F8F7F6F5 + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410S.buffer); + Ld1410HandleTargetData(); + } + } + else if (config_header) { // FDFCFBFA + if (Ld2410Match(LD2410_config_footer, len -4)) { // 04030201 + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410S.buffer); + Ld1410HandleConfigData(); + LD2410Serial->setReadChunkMode(0); // Disable chunk mode fixing Hardware Watchdogs + } + } + } + LD2410S.byte_counter = 0; // Finished or bad received footer + break; // Exit loop to satisfy yields + } + // If here then LD2410.byte_counter could still be partial correct for next loop +} + +void Ld2410SendCommand(uint32_t command, uint8_t *val = nullptr, uint32_t val_len = 0); +void Ld2410SendCommand(uint32_t command, uint8_t *val, uint32_t val_len) { + uint32_t len = val_len +12; + uint8_t buffer[len]; + buffer[0] = 0xFD; + buffer[1] = 0xFC; + buffer[2] = 0xFB; + buffer[3] = 0xFA; + buffer[4] = val_len +2; + buffer[5] = 0x00; + buffer[6] = command; + buffer[7] = 0x00; + if (val) { + for (uint32_t i = 0; i < val_len; i++) { + buffer[8 +i] = val[i]; + } + } + buffer[8 +val_len] = 0x04; + buffer[9 +val_len] = 0x03; + buffer[10 +val_len] = 0x02; + buffer[11 +val_len] = 0x01; + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Send %*_H"), len, buffer); + + LD2410Serial->setReadChunkMode(1); // Enable chunk mode introducing possible Hardware Watchdogs + LD2410Serial->flush(); + LD2410Serial->write(buffer, len); +} + +void Ld2410SetConfigMode(void) { // 0xFF + uint8_t value[2] = { 0x01, 0x00 }; + Ld2410SendCommand(LD2410S_CMND_START_CONFIGURATION, value, sizeof(value)); +} + +void Ld2410SetOutputMode(void) { + uint8_t value[6] = { 0,0,0,0,0,0 }; + value[2] = LD2410S.out_mode?1:0; + Ld2410SendCommand(LD2410S_CMND_OUTPUT_MODE, value, sizeof(value)); +} + +void Ld2410ReadCommonParameters(void) { + /* + Detection of the closest distance door 0x0A 0~16 + Detection of the farthest distance door 0x05 1~16 + No delay time 0x06 10 ~ 120s + Status reporting frequency 0x02 0.5 ~ 8(0.5SteppingHz) + Distance reporting frequency 0x0C 0.5 ~ 8(0.5SteppingHz) + Response speed 0x0B 5(normal)/10(fast)- +*/ + uint8_t value[12] = { 0x0A, 0x00, 0x05, 0x00, 0x06, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x0B, 0x00}; + Ld2410SendCommand(LD2410S_CMND_READ_COMMON, value, sizeof(value)); +} + +void Ld2410SetCommonParametrs(void) { + uint8_t value[36] = { 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00 }; +value[2] = LD2410S.near_end; +value[8] = LD2410S.far_end; +value[14] = LD2410S.hold_duration; +value[20] = LD2410S.status_report_f; +value[26] = LD2410S.distance_report_f; +value[32] = LD2410S.response_speed; +Ld2410SendCommand(LD2410S_CMND_SET_COMMON, value, sizeof(value)); +} + +#define Ld2410ReadTrigger() Ld2410ReadTriggerHold(LD2410S_CMND_READ_TRIGGER) +#define Ld2410ReadHold() Ld2410ReadTriggerHold(LD2410S_CMND_READ_HOLD) +void Ld2410ReadTriggerHold(uint8_t cmdn) { + uint8_t value[32] = {0,0, 1,0, 2,0, 3,0, 4,0, 5,0, 6,0, 7,0, 8,0, 9,0, 10,0, 11,0, 12,0, 13,0, 14,0, 15,0}; + Ld2410SendCommand(cmdn, value, sizeof(value)); +} + +void Ld2410AutoUpdate(void) { + uint8_t value[6] = { 0 }; + value[0] = LD2410S.auto_upd__scale; + value[2] = LD2410S.auto_upd_retension; + value[4] = LD2410S.auto_upd_time; + Ld2410SendCommand(LD2410S_CMND_AUTO_THRESHOLD, value, sizeof(value)); +} + +#define Ld2410WriteTrigger() Ld2410WriteTriggerHold(LD2410S_CMND_WRITE_TRIGGER) +#define Ld2410WriteHold() Ld2410WriteTriggerHold(LD2410S_CMND_WRITE_HOLD) +void Ld2410WriteTriggerHold(uint8_t cmnd) { + uint8_t value[96] = { 0 }; + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + value[i*6]=i; + if (cmnd == LD2410S_CMND_WRITE_TRIGGER) { + value[i*6+2]=LD2410S.trigger_energy[i]; + }else{ + value[i*6+2]=LD2410S.hold_energy[i]; + } + } + Ld2410SendCommand(cmnd, value, sizeof(value)); +} + +void Ld2410ExecCommand(uint8_t cmnd) { + LD2410S.step = 15; + LD2410S.next_step = cmnd; +} + +/********************************************************************************************/ + +void Ld2410Every100MSecond(void) { + if (LD2410S.step) { + LD2410S.step--; + switch (LD2410S.step) { + // boot module delay + case 200: + LD2410S.step = 15; + break; + // 100 auto update + case 99: + Ld2410AutoUpdate(); + LD2410S.step = 5; + break; + + // 70 - write trigger + case 69: + Ld2410WriteTrigger(); + LD2410S.retry = 2; + break; + case 67: + if (LD2410S.ack != LD2410S_CMND_WRITE_TRIGGER) { + if (LD2410S.retry--) { + LD2410S.step=70; + break; + } + } + LD2410S.step = 40; // reread params + break; + + // 65 - write hold + case 64: + Ld2410WriteHold(); + LD2410S.retry = 2; + break; + case 62: + if (LD2410S.ack != LD2410S_CMND_WRITE_HOLD) { + if (LD2410S.retry--) { + LD2410S.step=65; + break; + } + } + LD2410S.step = 40; // reread params + break; + + // 60 - Out mode + case 59: + Ld2410SetOutputMode(); + LD2410S.retry = 2; + break; + case 57: + if (LD2410S.ack != LD2410S_CMND_OUTPUT_MODE) { + if (LD2410S.retry--) { + LD2410S.step=60; + break; + } + } + LD2410S.step = 5; // End command + break; + + // 50 - write common + case 49: + Ld2410SetCommonParametrs(); + LD2410S.retry = 2; + break; + case 47: + if (LD2410S.ack != LD2410S_CMND_SET_COMMON) { + if (LD2410S.retry--) { + LD2410S.step=50; + break; + } + } + LD2410S.step = 40; // read params + break; + +// 40 - read params + case 39: + Ld2410ReadCommonParameters(); + LD2410S.retry = 4; + break; + case 37: + if (LD2410S.ack != LD2410S_CMND_READ_COMMON) { + if (LD2410S.retry--) { + LD2410S.step=40; + break; + } + } + break; +// 35 - read trigger + case 34: + Ld2410ReadTrigger(); + LD2410S.retry = 2; + break; + case 32: + if (LD2410S.ack != LD2410S_CMND_READ_TRIGGER) { + if (LD2410S.retry--) { + LD2410S.step=35; + break; + } + } + break; +// 30 - read hold + case 29: + Ld2410ReadHold(); + LD2410S.retry = 2; + break; + case 27: + if (LD2410S.ack != LD2410S_CMND_READ_HOLD) { + if (LD2410S.retry--) { + LD2410S.step=30; + break; + } + } + LD2410S.step=5; // End command + break; + +// 20 - loop +// 15 - Config mode + case 14: + Ld2410SetConfigMode(); // Stop running mode + break; + case 10: + if (LD2410S.ack != LD2410S_CMND_START_CONFIGURATION) { + if (LD2410S.retry--) { + LD2410S.step = 20; // Retry + } else { + LD2410S.step = 0; + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Not detected")); + } + } else { + LD2410S.step = LD2410S.next_step; + } + break; + case 1: + Ld2410SendCommand(LD2410S_CMND_END_CONFIGURATION); + break; + default: + break; + } + } +} + +void Ld2410EverySecond(void) { + if (LD2410S.human != LD2410S.human_last) { + LD2410S.human_last = LD2410S.human; + MqttPublishSensor(); + }else if ((LD2410S.report_type ==3 ) || (LD2410S.follow)) { + MqttPublishSensor(); + } +} + +void Ld2410Detect(void) { + if (PinUsed(GPIO_LD2410S_RX) && PinUsed(GPIO_LD2410S_TX)) { + LD2410S.buffer = (uint8_t*)malloc(LD2410S_BUFFER_SIZE); // Default 64 + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Buff size %d"), LD2410S_BUFFER_SIZE); + if (!LD2410S.buffer) { AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: No buff")); return; } + LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410S_RX), Pin(GPIO_LD2410S_TX), 2); + if (LD2410Serial->begin(115200)) { + if (LD2410Serial->hardwareSerial()) { ClaimSerial(); } +#ifdef ESP32 + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Serial UART%d"), LD2410Serial->getUart()); +#endif + LD2410S.retry = 4; + LD2410S.step = 250; + LD2410S.next_step = CMD_LD2410S_Read_Parametrs; + + } + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +const char kLd2410Commands[] PROGMEM = "LD2410S_|" // Prefix + "SetCommon|Out_Mode|AutoUpdate|Parameters|SetTrigger|SetHold|Help|ReRead|Follow"; + +void (* const Ld2410Command[])(void) PROGMEM = { + &CmndLd2410Common, &CmndLd2410OutMode, &CmndLd2410AutoUpdate, &CmndLd2410Response, &CmndLd2410Trigger, &CmndLd2410Hold, &CmndLd2410Help, &CmndLd2410ReRead, &CmndLd2410Follow}; + +void CmndLd2410Help(void) { + Response_P(PSTR("Available commands: LD2410S_Parameters (display parameters), LD2410S_ReRead (read param from module), LD2410S_SetCommon, LD2410S_SetTrigger, LD2410S_SetHold, LD2410S_Out_Mode (0-short, 1-normal), LD2410S_AutoUpdate, LD2410S_Follow (0/1 every 1 sec.)")); +} + +void CmndLd2410Response(void) { + Response_P(PSTR("{\"LD2410S_Common\":{\"Near Door\": %d,\"Far Door\":%d,\"Hold Time\":%d,\"Status freq\":%d,\"Distance freq\":%d,\"Response speed\":%d}"), + LD2410S.near_end, LD2410S.far_end, LD2410S.hold_duration, LD2410S.status_report_f, LD2410S.distance_report_f,LD2410S.response_speed); + ResponseAppend_P(PSTR(",\"Trigger values\":[")); + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + ResponseAppend_P(PSTR("%d"), LD2410S.trigger_energy[i]); + if (i < (LD2410S_NUM_GATES-1)) { + ResponseAppend_P(PSTR(",")); + } else { + ResponseAppend_P(PSTR("]")); + } + } + ResponseAppend_P(PSTR(",\"Hold values\":[")); + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + ResponseAppend_P(PSTR("%d"), LD2410S.hold_energy[i]); + if (i < (LD2410S_NUM_GATES-1)) { + ResponseAppend_P(PSTR(",")); + } else { + ResponseAppend_P(PSTR("]")); + } + } + ResponseJsonEnd(); +} + +void CmndLd2410ReRead(void) { + Ld2410ExecCommand(CMD_LD2410S_Read_Parametrs); + Response_P(PSTR("Accepted... Use LD2410S_Parameters after 1 second.")); +} + +void CmndLd2410Common(void) { + if (ArgC() == 6) { + uint32_t param[6] = { 0 }; + ParseParameters(6, param); + param[3]=(param[3]/5)*5; + param[3]=(param[4]/5)*5; + if (param[0]>16) {param[0] = 16;} + if (param[1]>16) {param[1] = 16;} + if (param[1]<1) {param[1] = 1;} + if (param[2]>120) {param[2] = 120;} + if (param[2]<10) {param[2] = 10;} + if (param[3]>80) {param[3] = 80;} + if (param[3]<5) {param[3] = 5;} + if (param[4]>80) {param[4] = 80;} + if (param[4]<5) {param[4] = 5;} + LD2410S.near_end = (uint8_t)param[0]; + LD2410S.far_end = (uint8_t)param[1]; + LD2410S.hold_duration = (uint8_t)param[2]; + LD2410S.status_report_f = (uint8_t)param[3]; + LD2410S.distance_report_f = (uint8_t)param[4]; + LD2410S.response_speed = (param[5]>5?10:5); + + Ld2410ExecCommand(CMD_LD2410S_Write_Common); +// Response_P(PSTR("Accepted.")); + CmndLd2410Response(); + } else { + Response_P(PSTR("Use LD2410S_SetCommon near_door,far_door,hold_time,status_freq,distance_freq,response_speed")); + } +} + +void CmndLd2410OutMode(void) { + char Argument[XdrvMailbox.data_len]; + ArgV(Argument,1); + LD2410S.out_mode = atoi(Argument); + Response_P(PSTR("{\"LD2410S_out_mode\":%d}"),LD2410S.out_mode); + Ld2410ExecCommand(CMD_LD2410S_Out_Mode); +} + +void CmndLd2410Follow(void) { + char Argument[XdrvMailbox.data_len]; + ArgV(Argument,1); + LD2410S.follow = atoi(Argument); + Response_P(PSTR("{\"LD2410S_Follow\":%d}"),LD2410S.follow); +} + +void CmndLd2410AutoUpdate(void) { + if (ArgC() != 3) { + Response_P(PSTR("Use LS2410S_AutoUpdate trigger_scale,retension_factor,scan_time")); + return; + } + uint32_t param[3] = {0}; + ParseParameters(3, param); + LD2410S.auto_upd__scale = param[0]; + LD2410S.auto_upd_retension = param[1]; + LD2410S.auto_upd_time = param[2]; + Ld2410ExecCommand(CMD_LD2410S_Auto_Update); + Response_P(PSTR("LD2410S Auto Update started...")); +} + +void CmndLd2410Trigger(void) { + if (ArgC() != 16) { + Response_P(PSTR("Use LS2410S_SetTrigger 1,2,..16")); + return; + } + uint32_t param[16] = { 0 }; + ParseParameters(16, param); + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + LD2410S.trigger_energy[i]=param[i]; + } + Ld2410ExecCommand(CMD_LD2410S_Write_Trigger); +// Response_P(PSTR("Accepted.")); + CmndLd2410Response(); +} + +void CmndLd2410Hold(void) { + if (ArgC() != 16) { + Response_P(PSTR("Use LS2410S_SetHold 1,2,..16")); + return; + } + uint32_t param[16] = { 0 }; + ParseParameters(16, param); + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + LD2410S.hold_energy[i]=param[i]; + } + Ld2410ExecCommand(CMD_LD2410S_Write_Hold); +// Response_P(PSTR("Accepted.")); + CmndLd2410Response(); +} + +/*********************************************************************************************\ + * Presentation +\*********************************************************************************************/ + +#ifdef USE_WEBSERVER +const char HTTP_SNS_LD2410_CM[] PROGMEM = + "{s}LD2410S " D_DETECT_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}"; + +const char HTTP_SNS_LD2410_UPD[] PROGMEM = + "{s}LD2410S Auto Update{m}%d " D_UNIT_PERCENT "{e}"; + +#endif + +#ifndef D_JSON_PEOPLE +#define D_JSON_PEOPLE "People" +#endif + +void Ld2410Show(bool json) { + float detect_distance = LD2410S.detect_distance; + + if (json) { + if (LD2410S.report_type != 3) { + ResponseAppend_P(PSTR(",\"LD2410S\":{\"" D_JSON_DISTANCE "\":%1_f, \"" D_JSON_PEOPLE "\":%d"), &detect_distance, LD2410S.human); + if (LD2410S.report_type == 1) { + ResponseAppend_P(PSTR(", \"Energy\":[")); + for (uint32_t i = 0; i < LD2410S_NUM_GATES; i++) { + ResponseAppend_P(PSTR("%d"), LD2410S.energy[i]); + if (i < (LD2410S_NUM_GATES-1)) { + ResponseAppend_P(PSTR(",")); + } else { + ResponseAppend_P(PSTR("]")); + } + } + } + ResponseJsonEnd(); + }else{ + ResponseAppend_P(PSTR(",\"LD2410S\":{\"Update threshold\":\"%1d%%\"}"), LD2410S.detect_distance); + } +#ifdef USE_WEBSERVER + } else { + if (LD2410S.report_type != 3) { + WSContentSend_PD(HTTP_SNS_LD2410_CM, &detect_distance); + }else{ + WSContentSend_PD(HTTP_SNS_LD2410_UPD, LD2410S.detect_distance); + } + #endif + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns102(uint32_t function) { + bool result = false; + + if (FUNC_INIT == function) { + Ld2410Detect(); + } + else if (LD2410Serial) { + switch (function) { + case FUNC_LOOP: + case FUNC_SLEEP_LOOP: + Ld2410Input(); + break; + case FUNC_EVERY_100_MSECOND: + Ld2410Every100MSecond(); + break; + case FUNC_EVERY_SECOND: + Ld2410EverySecond(); + break; + case FUNC_JSON_APPEND: + Ld2410Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + Ld2410Show(0); + break; +#endif // USE_WEBSERVER + case FUNC_COMMAND: + result = DecodeCommand(kLd2410Commands, Ld2410Command); + break; + } + } + return result; +} + +#endif // USE_LD2410S From 0f2b3b189880dc6ff9474c0abb6874b39611196d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 25 Oct 2024 17:27:39 +0200 Subject: [PATCH 042/205] Update changelogs --- CHANGELOG.md | 2 ++ RELEASENOTES.md | 2 ++ tasmota/include/tasmota_types.h | 2 +- tools/decode-status.py | 5 +++-- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0337f1a19..e93f5843b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ All notable changes to this project will be documented in this file. - Support for Shelly DALI Dimmer Gen3 (See tips and template in file xdrv_75_dali.ino) - HASPmota `haspmota.get_pages()` to get the sorted list of pages (#22358) - Support for US AQI and EPA AQI in PMS5003x sensors (#22294) +- HLK-LD2410 Engineering mode (#21880) +- Support for HLK-LD2410S 24GHz smart wave motion sensor (#22253) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5562fe537..d50581802 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -122,7 +122,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliTarget` to set light control broadcast, group number or gear number - DALI inverted signal configuration using GPIO DALI RX_i/TX_i - Support for Shelly DALI Dimmer Gen3 (See tips and template in file xdrv_75_dali.ino) +- Support for HLK-LD2410S 24GHz smart wave motion sensor [#22253](https://github.com/arendst/Tasmota/issues/22253) - Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) +- HLK-LD2410 Engineering mode [#21880](https://github.com/arendst/Tasmota/issues/21880) - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index 3ad75c19a..a7a6dabc1 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -194,7 +194,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t neopool_outputsensitive : 1; // bit 11 (v13.2.0.1) - SetOption157 - (NeoPool) Output sensitive data (1) uint32_t mqtt_disable_modbus : 1; // bit 12 (v13.3.0.5) - SetOption158 - (MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead uint32_t counter_both_edges : 1; // bit 13 (v13.3.0.5) - SetOption159 - (Counter) Enable counting on both rising and falling edge (1) - uint32_t ld2410_use_pin : 1; // bit 14 (development) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1) + uint32_t ld2410_use_pin : 1; // bit 14 (v14.3.0.2) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1) uint32_t spare15 : 1; // bit 15 uint32_t spare16 : 1; // bit 16 uint32_t spare17 : 1; // bit 17 diff --git a/tools/decode-status.py b/tools/decode-status.py index 5c99b1a9b..87d71125b 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -215,7 +215,8 @@ a_setoption = [[ "(NeoPool) Output sensitive data (1)", "(MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead", "(Counter) Enable counting on both rising and falling edge (1)", - "","", + "(LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1)", + "", "","","","", "","","","", "","","","", @@ -339,7 +340,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v14.2.0.4 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v14.3.0.2 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From b5a487a5952d1b655b40bc27180176031c92dc83 Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Fri, 25 Oct 2024 19:25:49 +0200 Subject: [PATCH 043/205] widget support for Berry/MI32 dashboard (#22359) --- lib/libesp32/berry_tasmota/src/be_MI32_lib.c | 8 ++- .../xdrv_52_3_berry_MI32.ino | 51 +++++++++++++------ .../tasmota_xsns_sensor/xsns_62_esp32_mi.ino | 39 +++++++++----- 3 files changed, 67 insertions(+), 31 deletions(-) diff --git a/lib/libesp32/berry_tasmota/src/be_MI32_lib.c b/lib/libesp32/berry_tasmota/src/be_MI32_lib.c index 5078de941..3babcf3c4 100644 --- a/lib/libesp32/berry_tasmota/src/be_MI32_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_MI32_lib.c @@ -1,6 +1,6 @@ /******************************************************************** * Tasmota lib - * + * * To use: `import MI32` *******************************************************************/ #include "be_constobj.h" @@ -25,6 +25,9 @@ BE_FUNC_CTYPE_DECLARE(be_MI32_set_hum, "", "ii"); extern void be_MI32_set_temp(int slot, int temp_val); BE_FUNC_CTYPE_DECLARE(be_MI32_set_temp, "", "ii"); +extern bbool be_MI32_widget(const char *sbuf, void* function); +BE_FUNC_CTYPE_DECLARE(be_MI32_widget, "b", "s[c]"); + #include "be_fixed_MI32.h" /* @const_object_info_begin @@ -35,12 +38,13 @@ module MI32 (scope: global) { set_bat, ctype_func(be_MI32_set_bat) set_hum, ctype_func(be_MI32_set_hum) set_temp, ctype_func(be_MI32_set_temp) + widget, ctype_func(be_MI32_widget) } @const_object_info_end */ /******************************************************************** * Tasmota lib - * + * * To use: `import BLE` *******************************************************************/ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino index 6db4ec644..2f506828a 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino @@ -28,14 +28,14 @@ /*********************************************************************************************\ * Native functions mapped to Berry functions - * - * + * + * \*********************************************************************************************/ extern "C" { /******************************************************************** ** MI32 - sensor specific functions -********************************************************************/ +********************************************************************/ extern uint32_t MI32numberOfDevices(); extern char * MI32getDeviceName(uint32_t slot); @@ -44,15 +44,21 @@ extern "C" { extern void MI32setTemperatureForSlot(uint32_t slot, float value); extern uint8_t * MI32getDeviceMAC(uint32_t slot); + struct { + const char * data = nullptr; + size_t size = 0; + void* callback = nullptr; + } be_MI32Widget; + int be_MI32_devices(void) { return MI32numberOfDevices(); } - void be_MI32_set_bat(int slot, int bat_val){ + void be_MI32_set_bat(int slot, int bat_val){ MI32setBatteryForSlot(slot,bat_val); } - const char* be_MI32_get_name(int slot){ + const char* be_MI32_get_name(int slot){ return MI32getDeviceName(slot); } @@ -65,14 +71,26 @@ extern "C" { return buffer; } - void be_MI32_set_hum(int slot, int hum_val){ + void be_MI32_set_hum(int slot, int hum_val){ MI32setHumidityForSlot(slot,hum_val); } - void be_MI32_set_temp(int slot, int temp_val){ + void be_MI32_set_temp(int slot, int temp_val){ MI32setTemperatureForSlot(slot,temp_val); } + bool be_MI32_widget(const char* sbuf, void* function){ + if (function){ + be_MI32Widget.callback = function; + } + if(be_MI32Widget.size == 0){ + be_MI32Widget.data = sbuf; + be_MI32Widget.size = strlen(sbuf); + return true; + } + return false; + } + /******************************************************************** ** BLE - generic BLE functions @@ -103,12 +121,12 @@ extern "C" { } void be_BLE_reg_conn_cb(void* function, uint8_t *buffer); - void be_BLE_reg_conn_cb(void* function, uint8_t *buffer){ + void be_BLE_reg_conn_cb(void* function, uint8_t *buffer){ MI32setBerryConnCB(function,buffer); } void be_BLE_reg_server_cb(void* function, uint8_t *buffer); - void be_BLE_reg_server_cb(void* function, uint8_t *buffer){ + void be_BLE_reg_server_cb(void* function, uint8_t *buffer){ MI32setBerryServerCB(function,buffer); } @@ -145,7 +163,7 @@ extern "C" { } void be_BLE_set_service(struct bvm *vm, const char *Svc, bbool discoverAttributes); - void be_BLE_set_service(struct bvm *vm, const char *Svc, bbool discoverAttributes){ + void be_BLE_set_service(struct bvm *vm, const char *Svc, bbool discoverAttributes){ bool _discoverAttributes = false; if(discoverAttributes){ _discoverAttributes = discoverAttributes ; @@ -157,7 +175,7 @@ extern "C" { void be_BLE_set_characteristic(struct bvm *vm, const char *Chr); void be_BLE_set_characteristic(struct bvm *vm, const char *Chr){ - + if (MI32setBerryCtxChr(Chr)) return; be_raisef(vm, "ble_error", "BLE: could not set characteristic"); @@ -166,7 +184,7 @@ extern "C" { void be_BLE_run(struct bvm *vm, uint8_t operation, bbool response, int32_t arg1); void be_BLE_run(struct bvm *vm, uint8_t operation, bbool response, int32_t arg1){ int32_t argc = be_top(vm); // Get the number of arguments - bool _response = false; + bool _response = false; if(response){ _response = response; } @@ -181,7 +199,7 @@ extern "C" { } void be_BLE_adv_block(struct bvm *vm, uint8_t *buf, size_t size, uint8_t type); - void be_BLE_adv_block(struct bvm *vm, uint8_t *buf, size_t size, uint8_t type){ + void be_BLE_adv_block(struct bvm *vm, uint8_t *buf, size_t size, uint8_t type){ if(!be_BLE_MAC_size(vm, size)){ return; } @@ -190,12 +208,12 @@ extern "C" { _type = type; } if(MI32addMACtoBlockList(buf, _type)) return; - + be_raisef(vm, "ble_error", "BLE: could not block MAC"); } void be_BLE_adv_watch(struct bvm *vm, uint8_t *buf, size_t size, uint8_t type); - void be_BLE_adv_watch(struct bvm *vm, uint8_t *buf, size_t size, uint8_t type){ + void be_BLE_adv_watch(struct bvm *vm, uint8_t *buf, size_t size, uint8_t type){ if(!be_BLE_MAC_size(vm, size)){ return; } @@ -331,7 +349,7 @@ __commands 201 add/set advertisement 202 add/set scan response -211 add/set characteristic +211 add/set characteristic __response 221 onRead @@ -358,5 +376,6 @@ MI32.get_MAC(slot) MI32.set_bat(slot,int) MI32.set_hum(slot,float) MI32.set_temp(slot,float) +MI32.widget(string[,cb]) */ \ No newline at end of file diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino index b336ec17c..f0d816744 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino @@ -686,7 +686,7 @@ void MI32Init(void) { if (MI32.mode.init) { return; } if (TasmotaGlobal.global_state.wifi_down && TasmotaGlobal.global_state.eth_down) { - if (!(WIFI_MANAGER == Wifi.config_type || WIFI_MANAGER_RESET_ONLY == Wifi.config_type)) return; + if (!(WIFI_MANAGER == Wifi.config_type || WIFI_MANAGER_RESET_ONLY == Wifi.config_type)) return; } if (!TasmotaGlobal.global_state.wifi_down) { @@ -919,6 +919,14 @@ extern "C" { return _name; } + void MI32sendBerryWidget() { + if(be_MI32Widget.size != 0) { + WSContentSend(be_MI32Widget.data, be_MI32Widget.size); + be_MI32Widget.data = nullptr; + be_MI32Widget.size = 0; + } + } + } //extern "C" /*********************************************************************************************\ @@ -1187,7 +1195,7 @@ bool MI32ConnectActiveSensor(){ // only use inside a task !! /** * @brief Retrieves all services of the connected BLE device and stores the result into the transfer buffer of Berry's BLE module -* buffer format: + * buffer format: * first byte: number of services * next byte: format of the UUID in bits, next N bytes: the UUID as 16-bit-uint or uint8_t buffer of 16 bytes * ... next service @@ -1212,13 +1220,13 @@ void MI32ConnectionGetServices(){ /** * @brief Retrieves all characteristics of the given service and stores the result into the transfer buffer of Berry's BLE module - * buffer format: + * buffer format: * first byte: number of characteristics * next byte: format of the UUID in bits, next N bytes: the UUID as 16-bit-uint or uint8_t buffer of 16 bytes * next byte: properties in a bitfield * ... next characteristic - * - * @param pSvc + * + * @param pSvc */ void MI32ConnectionGetCharacteristics(NimBLERemoteService* pSvc); void MI32ConnectionGetCharacteristics(NimBLERemoteService* pSvc){ @@ -1478,7 +1486,7 @@ bool MI32StartServerTask(){ void MI32ServerSetAdv(NimBLEServer *pServer, std::vector& servicesToStart, bool &shallStartServices); /** * @brief Sets the advertisement message from the data of the context, could be regular advertisement or scan response - * + * * @param pServer - our server instance * @param servicesToStart - for the first run, this vector holds all our services, would not be used for later modifications of the advertisement message * @param shallStartServices - true only for the first call, which will finish the construction of the server by starting all services @@ -1570,7 +1578,7 @@ void MI32ServerSetAdv(NimBLEServer *pServer, std::vector& servic void MI32ServerSetCharacteristic(NimBLEServer *pServer, std::vector& servicesToStart, bool &shallStartServices); /** * @brief Create a characteristic or modify its value with data of the context - * + * * @param pServer - our server instance * @param servicesToStart - before the finish of the server construction, a characteristic and maybe the holding service will be created and added to this vector * @param shallStartServices - true, if the server construction is not finished by first setting of advertisement data @@ -2083,7 +2091,7 @@ uint16_t MI32checkRPA(uint8_t *addr) { if(data[13] == addr[3] && data[14] == addr[4] && data[15] == addr[5]) { MIBLEsensors[idx].lastTime = Rtc.local_time; return idx; - } + } } return 0xff; } @@ -2120,7 +2128,7 @@ void MI32HandleEveryDevice(NimBLEAdvertisedDevice* advertisedDevice, uint8_t add if(MI32.option.directBridgeMode == 1){ MI32.mode.shallTriggerTele = 1; _sensor.shallSendMQTT = 1; - } + } } } @@ -2156,7 +2164,7 @@ void MI32BLELoop() if(MI32.mode.connected == 1 && BLERingBufferQueue != nullptr && MI32.mode.triggerBerryConnCB == 0) { size_t size; BLERingBufferItem_t *q = (BLERingBufferItem_t *)xRingbufferReceive(BLERingBufferQueue, &size, pdMS_TO_TICKS(1)); - + if(q != nullptr){ if(q->length != 0){ memcpy(MI32.conCtx->buffer,&q->length,q->length + 1); @@ -2184,7 +2192,7 @@ void MI32BLELoop() if(MI32.mode.connected == 0 && BLERingBufferQueue != nullptr){ size_t size; BLERingBufferItem_t *q = (BLERingBufferItem_t *)xRingbufferReceive(BLERingBufferQueue, &size, pdMS_TO_TICKS(1)); - + if(q != nullptr){ if(q->length != 0){ memcpy(MI32.conCtx->buffer,&q->length,q->length + 1); @@ -2361,10 +2369,13 @@ void CmndMi32Option(void){ \*********************************************************************************************/ #ifdef USE_MI_EXT_GUI bool MI32HandleWebGUIResponse(void){ + if(be_MI32Widget.callback != nullptr){ + ((void(*)())be_MI32Widget.callback)(); + } char tmp[16]; WebGetArg(PSTR("wi"), tmp, sizeof(tmp)); if (strlen(tmp)) { - WSContentBegin(200, CT_PLAIN); + WSContentBegin(200, CT_PLAIN); if(MI32.widgetSlot!=0){ for(uint32_t i=0;i<32;i++){ if(bitRead(MI32.widgetSlot,i)){ @@ -2373,6 +2384,8 @@ bool MI32HandleWebGUIResponse(void){ break; } } + } else { + MI32sendBerryWidget(); } WSContentEnd(); return true; @@ -2585,7 +2598,7 @@ void MI32InitGUI(void){ #endif //USE_MI_ESP32_ENERGY #ifdef USE_WEBCAM MI32sendCamWidget(); -#endif //USE_WEBCAM +#endif //USE_WEBCAM WSContentSend_P(PSTR("")); WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); From 98b04f5029c7dbd22e9a0b13ab8967a07161e435 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Sat, 26 Oct 2024 11:06:37 +0200 Subject: [PATCH 044/205] Update Italian language (#22362) --- tasmota/language/it_IT.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index f756f44b7..5cdee385c 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.4.0.1 - Last update 22.10.2024 + * Updated until v9.4.0.1 - Last update 26.10.2024 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -377,7 +377,7 @@ #define D_MQTT_TOPIC "Topic MQTT" #define D_MQTT_GROUP_TOPIC "Gruppo topic MQTT" #define D_MQTT_FULL_TOPIC "Full topic MQTT" -#define D_MQTT_NO_RETAIN "MQTT No Retain" +#define D_MQTT_NO_RETAIN "MQTT Nessuna conservazione" #define D_MDNS_DISCOVERY "Ricerca mDNS" #define D_MDNS_ADVERTISE "Notifica mDNS" #define D_ESP_CHIP_ID "ID chip ESP" @@ -774,8 +774,8 @@ #define D_SENSOR_WE517_RX "WE517 - RX" #define D_SENSOR_LD2410_TX "LD2410 - TX" #define D_SENSOR_LD2410_RX "LD2410 - RX" -#define D_SENSOR_LD2410S_TX "LD2410S Tx" -#define D_SENSOR_LD2410S_RX "LD2410S Rx" +#define D_SENSOR_LD2410S_TX "LD2410S - TX" +#define D_SENSOR_LD2410S_RX "LD2410S - RX" #define D_GPIO_TM1621_CS "TM1621 - CS" #define D_GPIO_TM1621_WR "TM1621 - WR" #define D_GPIO_TM1621_RD "TM1621 - RD" @@ -1282,13 +1282,13 @@ #define D_SENSOR_PIPSOLAR_RX "Pipsolar - RX" // xsns_102_ld2410.ino -#define D_MOVING_DISTANCE "Distanza in movimento" -#define D_STATIC_DISTANCE "Distanza statica" -#define D_DETECT_DISTANCE "Rileva distanza" -#define D_MOVING_ENERGY_T "Moving target" -#define D_STATIC_ENERGY_T "Target statico" -#define D_LD2410_PIN_STATE "Stato pin di uscita" -#define D_LD2410_LIGHT "Sensore di luce" +#define D_MOVING_DISTANCE "Distanza in movimento" +#define D_STATIC_DISTANCE "Distanza statica" +#define D_DETECT_DISTANCE "Rileva distanza" +#define D_MOVING_ENERGY_T "Obiettivo in movimento" +#define D_STATIC_ENERGY_T "Obiettivo statico" +#define D_LD2410_PIN_STATE "Stato pin di uscita" +#define D_LD2410_LIGHT "Sensore di luce" // xsns_115_wooliis.ino #define D_IMPORT "Importa" From 227e5f24b67e25568f966d7718d3d80d1a44c08f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:00:17 +0100 Subject: [PATCH 045/205] Enable DALI in ESP32 Tasmota --- tasmota/include/tasmota_configurations.h | 2 ++ tasmota/include/tasmota_configurations_ESP32.h | 2 ++ tasmota/my_user_config.h | 8 ++------ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h index 03aa2828b..7a1118b9c 100644 --- a/tasmota/include/tasmota_configurations.h +++ b/tasmota/include/tasmota_configurations.h @@ -702,6 +702,7 @@ #define USE_TASMOTA_DISCOVERY // Enable Tasmota Discovery support (+2k code) #undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set #undef USE_KNX // Disable KNX IP Protocol Support +#undef USE_DALI // Disable support for DALI gateway (+5k code) //#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) @@ -867,6 +868,7 @@ #undef USE_TELEGRAM // Disable support for Telegram protocol (+49k code, +7.0k mem and +4.8k additional during connection handshake) //#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set #undef USE_KNX // Disable KNX IP Protocol Support +#undef USE_DALI // Disable support for DALI gateway (+5k code) //#undef USE_WEBSERVER // Disable Webserver #undef USE_GPIO_VIEWER // Disable GPIO Viewer to see realtime GPIO states (+5k6 code) #undef USE_ENHANCED_GUI_WIFI_SCAN // Disable wifi scan output with BSSID (+0k5 code) diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 07973b225..4b89f545d 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -60,6 +60,7 @@ #undef USE_TELEGRAM // Disable support for Telegram protocol (+49k code, +7.0k mem and +4.8k additional during connection handshake) //#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set #undef USE_KNX // Disable KNX IP Protocol Support +#undef USE_DALI // Disable support for DALI gateway (+5k code) //#undef USE_WEBSERVER // Disable Webserver #undef USE_GPIO_VIEWER // Enable GPIO Viewer to see realtime GPIO states (+5k6 code) #undef USE_ENHANCED_GUI_WIFI_SCAN // Disable wifi scan output with BSSID (+0k5 code) @@ -800,6 +801,7 @@ #ifndef USE_KNX #define USE_KNX // Enable KNX IP Protocol Support (+23k code, +3k3 mem) #endif +#define USE_DALI // Add support for DALI gateway (+5k code) #endif // FIRMWARE_TASMOTA32 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 1a7766d8e..39a78820b 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -880,13 +880,13 @@ //#define USE_VINDRIKTNING // Add support for IKEA VINDRIKTNING particle concentration sensor (+0k6 code) // #define VINDRIKTNING_SHOW_PM1 // Display undocumented/supposed PM1.0 values // #define VINDRIKTNING_SHOW_PM10 // Display undocumented/supposed PM10 values -//#define USE_LD2410 // Add support for HLK-LD2410 24GHz smart wave motion sensor (+3k7 code) -//#define USE_LD2410S // Add support for HLK-LD2410S 24GHz smart wave motion sensor (+4k6 code) +//#define USE_LD2410 // Add support for HLK-LD2410 24GHz smart wave motion sensor (+2k8 code) //#define USE_LOX_O2 // Add support for LuminOx LOX O2 Sensor (+0k8 code) //#define USE_GM861 // Add support for GM861 1D and 2D Bar Code Reader (+1k3 code) // #define GM861_DECODE_AIM // Decode AIM-id (+0k3 code) // #define GM861_HEARTBEAT // Enable heartbeat (+0k2 code) //#define USE_WOOLIIS // Add support for Wooliis Hall Effect Coulometer or Battery capacity monitor (+1k6 code) +//#define USE_DALI // Add support for DALI gateway (+5k code) // -- Power monitoring sensors -------------------- #define USE_ENERGY_SENSOR // Add support for Energy Monitors (+14k code) @@ -1079,10 +1079,6 @@ //#define USE_FLOWRATEMETER // Add support for water flow meter YF-DN50 and similary (+1k7 code) -// #define USE_DALI // Add support for DALI 1 bridge (+2k1 code) - #define DALI_IN_INVERT 0 // DALI RX inverted - #define DALI_OUT_INVERT 0 // DALI TX inverted - // -- Thermostat control ---------------------------- //#define USE_THERMOSTAT // Add support for Thermostat #define THERMOSTAT_CONTROLLER_OUTPUTS 1 // Number of outputs to be controlled independently From bca4211500a7a5dde013dd89b549a33ab9983eaa Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 27 Oct 2024 15:32:40 +0100 Subject: [PATCH 046/205] Fix ESP32 energy margins reporting when powered off --- tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index 26e7ec27f..5d03055b7 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -821,12 +821,12 @@ void EnergyMarginCheck(void) { jsonflg = true; } } - if (jsonflg) { - ResponseJsonEndEnd(); - MqttPublishTele(PSTR(D_RSLT_MARGINS)); - EnergyMqttShow(); - Energy->margin_stable = 3; // Allow 2 seconds to stabilize before reporting - } + } + if (jsonflg) { + ResponseJsonEndEnd(); + MqttPublishTele(PSTR(D_RSLT_MARGINS)); + EnergyMqttShow(); + Energy->margin_stable = 3; // Allow 2 seconds to stabilize before reporting } // Max Power From 19fcaf8866b8ac1f541f18c66f5e4aeba8dc242a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 27 Oct 2024 15:54:39 +0100 Subject: [PATCH 047/205] Add command IfxFeed --- .../tasmota_xdrv_driver/xdrv_59_influxdb.ino | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino b/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino index c8c6122d9..298fe5cc6 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino @@ -41,6 +41,7 @@ * IfxSensor - Set Influxdb sensor logging off (0) or on (1) * IfxRP - Set Influxdb retention policy * IfxLog - Set Influxdb logging level (4 = default) + * IfxFeed - Feed Influxdb with JSON data * * The following triggers result in automatic influxdb numeric feeds without appended time: * - this driver initiated state message @@ -476,6 +477,7 @@ void InfluxDbLoop(void) { #define D_CMND_INFLUXDBPERIOD "Period" #define D_CMND_INFLUXDBSENSOR "Sensor" #define D_CMND_INFLUXDBRP "RP" +#define D_CMND_INFLUXDBFEED "Feed" const char kInfluxDbCommands[] PROGMEM = D_PRFX_INFLUXDB "|" // Prefix "|" D_CMND_INFLUXDBLOG "|" @@ -483,7 +485,8 @@ const char kInfluxDbCommands[] PROGMEM = D_PRFX_INFLUXDB "|" // Prefix D_CMND_INFLUXDBUSER "|" D_CMND_INFLUXDBORG "|" D_CMND_INFLUXDBPASSWORD "|" D_CMND_INFLUXDBTOKEN "|" D_CMND_INFLUXDBDATABASE "|" D_CMND_INFLUXDBBUCKET "|" - D_CMND_INFLUXDBPERIOD "|" D_CMND_INFLUXDBSENSOR "|" D_CMND_INFLUXDBRP; + D_CMND_INFLUXDBPERIOD "|" D_CMND_INFLUXDBSENSOR "|" + D_CMND_INFLUXDBRP "|" D_CMND_INFLUXDBFEED; void (* const InfluxCommand[])(void) PROGMEM = { &CmndInfluxDbState, &CmndInfluxDbLog, @@ -491,7 +494,8 @@ void (* const InfluxCommand[])(void) PROGMEM = { &CmndInfluxDbUser, &CmndInfluxDbUser, &CmndInfluxDbPassword, &CmndInfluxDbPassword, &CmndInfluxDbDatabase, &CmndInfluxDbDatabase, - &CmndInfluxDbPeriod, &CmndInfluxDbSensor, &CmndInfluxDbRP }; + &CmndInfluxDbPeriod, &CmndInfluxDbSensor, + &CmndInfluxDbRP, &CmndInfluxDbFeed }; void InfluxDbReinit(void) { IFDB.init = false; @@ -599,6 +603,15 @@ void CmndInfluxDbPeriod(void) { ResponseCmndNumber(Settings->influxdb_period); } +void CmndInfluxDbFeed(void) { + // IfxFeed {"Data":10} + if ((XdrvMailbox.data_len > 0) && ('{' == XdrvMailbox.data[0])) { + Response_P(XdrvMailbox.data); + InfluxDbProcessJson(); + ResponseCmndDone(); + } +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ From faf6e66e322d8d2858de39c822eee2bf5e2522bd Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 27 Oct 2024 17:31:31 +0100 Subject: [PATCH 048/205] Fix map_double compile error --- tasmota/tasmota_support/support_float.ino | 4 ++++ tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino | 7 +------ tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino | 12 ++++++------ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tasmota/tasmota_support/support_float.ino b/tasmota/tasmota_support/support_float.ino index ac7527302..c6bfa9787 100644 --- a/tasmota/tasmota_support/support_float.ino +++ b/tasmota/tasmota_support/support_float.ino @@ -481,3 +481,7 @@ float Polynomialf(const float *factors, uint32_t degree, float x) { } return r; } + +float map_float(float x, float in_min, float in_max, float out_min, float out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino index b68341668..d43b93aaf 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino @@ -2464,7 +2464,7 @@ void CmndScale(void) float fromHigh = CharToFloat(ArgV(argument, 3)); float toLow = CharToFloat(ArgV(argument, 4)); float toHigh = CharToFloat(ArgV(argument, 5)); - float value = map_double(valueIN, fromLow, fromHigh, toLow, toHigh); + float value = map_float(valueIN, fromLow, fromHigh, toLow, toHigh); dtostrfd(value, Settings->flag2.calc_resolution, rules_vars[XdrvMailbox.index -1]); bitSet(Rules.vars_event, XdrvMailbox.index -1); } else { @@ -2475,11 +2475,6 @@ void CmndScale(void) } } -float map_double(float x, float in_min, float in_max, float out_min, float out_max) -{ - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} - /*********************************************************************************************\ * Interface \*********************************************************************************************/ diff --git a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino index 1da6a0058..88380531c 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino @@ -390,17 +390,17 @@ int usaEpaStandardPm2d5Adjustment(int pm25_standard, int relative_humidity) int compute_us_aqi(int pm25_standard) { if (pm25_standard <= 9) { - return map_double(pm25_standard, 0, 9, 0, 50); + return map_float(pm25_standard, 0, 9, 0, 50); } else if (pm25_standard <= 35) { - return map_double(pm25_standard, 9.1f, 35.4f, 51, 100); + return map_float(pm25_standard, 9.1f, 35.4f, 51, 100); } else if (pm25_standard <= 55) { - return map_double(pm25_standard, 35.5f, 55.4f, 101, 150); + return map_float(pm25_standard, 35.5f, 55.4f, 101, 150); } else if (pm25_standard <= 125) { - return map_double(pm25_standard, 55.5f, 125.4f, 151, 200); + return map_float(pm25_standard, 55.5f, 125.4f, 151, 200); } else if (pm25_standard <= 225) { - return map_double(pm25_standard, 125.5f, 225.4f, 201, 300); + return map_float(pm25_standard, 125.5f, 225.4f, 201, 300); } else if (pm25_standard <= 325) { - return map_double(pm25_standard, 225.5f, 325.4f, 301, 500); + return map_float(pm25_standard, 225.5f, 325.4f, 301, 500); } else { return 500; } From 37f42b474f7116dcac40aeba218161303f486edb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:13:43 +0100 Subject: [PATCH 049/205] Fix DALI init sequence (#22371) --- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 44 +++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index e553dd594..4fe44e7a1 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -860,29 +860,33 @@ bool DaliSetChannels(void) { /*-------------------------------------------------------------------------------------------*/ bool DaliInit(void) { + int pin_tx = -1; + bool invert_tx = false; + if (PinUsed(GPIO_DALI_TX)) { + pin_tx = Pin(GPIO_DALI_TX); + } + else if (PinUsed(GPIO_DALI_TX_INV)) { + pin_tx = Pin(GPIO_DALI_TX_INV); + invert_tx = true; + } + int pin_rx = -1; + bool invert_rx = false; + if (PinUsed(GPIO_DALI_RX)) { + pin_rx = Pin(GPIO_DALI_RX); + } + else if (PinUsed(GPIO_DALI_RX_INV)) { + pin_rx = Pin(GPIO_DALI_RX_INV); + invert_rx = true; + } + if ((-1 == pin_tx) || (-1 == pin_rx)) { return false; } + Dali = (DALI*)calloc(sizeof(DALI), 1); if (!Dali) { return false; } - Dali->pin_tx = 255; - if (PinUsed(GPIO_DALI_TX)) { - Dali->pin_tx = Pin(GPIO_DALI_TX); - } - else if (PinUsed(GPIO_DALI_TX_INV)) { - Dali->pin_tx = Pin(GPIO_DALI_TX_INV); - Dali->invert_tx = true; - } - Dali->pin_rx = 255; - if (PinUsed(GPIO_DALI_RX)) { - Dali->pin_rx = Pin(GPIO_DALI_RX); - } - else if (PinUsed(GPIO_DALI_RX_INV)) { - Dali->pin_rx = Pin(GPIO_DALI_RX_INV); - Dali->invert_rx = true; - } - if ((255 == Dali->pin_tx) || (255 == Dali->pin_rx)) { - free(Dali); - return false; - } + Dali->pin_tx = pin_tx; + Dali->invert_tx = invert_tx; + Dali->pin_rx = pin_rx; + Dali->invert_rx = invert_rx; AddLog(LOG_LEVEL_INFO, PSTR("DLI: GPIO%d(RX%s) and GPIO%d(TX%s)"), Dali->pin_rx, (Dali->invert_rx)?"i":"", Dali->pin_tx, (Dali->invert_tx)?"i":""); From 4f2c1f3499a2f33af1da3d792f14fa63ed5fdb95 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:51:27 +0100 Subject: [PATCH 050/205] Fix Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 (#22367) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/tasmota.ino | 8 ++++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e93f5843b..233df30c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ All notable changes to this project will be documented in this file. - Shutter optimized behavior to publish shutter data with sensor request (#22353) ### Fixed +- Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 (#22367) ### Removed - DALI inverted signal configuration using compile time defines diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d50581802..964d29c98 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -143,5 +143,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Fixed - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) +- Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 [#22367](https://github.com/arendst/Tasmota/issues/22367) ### Removed diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index e4f930685..13971aceb 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -409,15 +409,15 @@ void setup(void) { DisableBrownout(); // Workaround possible weak LDO resulting in brownout detection during Wifi connection #endif // DISABLE_ESP32_BROWNOUT - // restore GPIO16/17 if no PSRAM is found + // restore GPIO5/18 or 16/17 if no PSRAM is found which may be used by Ethernet among others if (!FoundPSRAM()) { // test if the CPU is not pico uint32_t pkg_version = bootloader_common_get_chip_ver_pkg(); if (pkg_version <= 3) { // D0WD, S0WD, D2WD - gpio_reset_pin(GPIO_NUM_16); // D0WD_PSRAM_CS_IO - gpio_reset_pin(GPIO_NUM_17); // D0WD_PSRAM_CLK_IO + gpio_reset_pin((gpio_num_t)CONFIG_D0WD_PSRAM_CS_IO); + gpio_reset_pin((gpio_num_t)CONFIG_D0WD_PSRAM_CLK_IO); // IDF5.3 fix esp_gpio_reserve used in init PSRAM - esp_gpio_revoke(BIT64(GPIO_NUM_16) | BIT64(GPIO_NUM_17)); + esp_gpio_revoke(BIT64(CONFIG_D0WD_PSRAM_CS_IO) | BIT64(CONFIG_D0WD_PSRAM_CLK_IO)); } } #endif // CONFIG_IDF_TARGET_ESP32 From e7317383859baefc37d2467978003332e86fdb4e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:03:27 +0100 Subject: [PATCH 051/205] Fix safeboot compilation (#22367) --- tasmota/tasmota.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 13971aceb..c21b7744c 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -409,6 +409,7 @@ void setup(void) { DisableBrownout(); // Workaround possible weak LDO resulting in brownout detection during Wifi connection #endif // DISABLE_ESP32_BROWNOUT +#ifndef FIRMWARE_SAFEBOOT // restore GPIO5/18 or 16/17 if no PSRAM is found which may be used by Ethernet among others if (!FoundPSRAM()) { // test if the CPU is not pico @@ -420,6 +421,7 @@ void setup(void) { esp_gpio_revoke(BIT64(CONFIG_D0WD_PSRAM_CS_IO) | BIT64(CONFIG_D0WD_PSRAM_CLK_IO)); } } +#endif // FIRMWARE_SAFEBOOT #endif // CONFIG_IDF_TARGET_ESP32 #endif // ESP32 From e14f014c962750f12a5f4c779680cb35c4731f41 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:18:42 +0100 Subject: [PATCH 052/205] Final fix. --- tasmota/tasmota.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index c21b7744c..6f312516f 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -410,6 +410,7 @@ void setup(void) { #endif // DISABLE_ESP32_BROWNOUT #ifndef FIRMWARE_SAFEBOOT +#ifndef CORE32SOLO1 // restore GPIO5/18 or 16/17 if no PSRAM is found which may be used by Ethernet among others if (!FoundPSRAM()) { // test if the CPU is not pico @@ -421,6 +422,7 @@ void setup(void) { esp_gpio_revoke(BIT64(CONFIG_D0WD_PSRAM_CS_IO) | BIT64(CONFIG_D0WD_PSRAM_CLK_IO)); } } +#endif // CORE32SOLO1 #endif // FIRMWARE_SAFEBOOT #endif // CONFIG_IDF_TARGET_ESP32 #endif // ESP32 From 104fec83fb8d252363897b315d54720791d34f3a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:23:48 +0100 Subject: [PATCH 053/205] add hybrid compile variant (#22374) --- pio-tools/post_esp32.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py index e296be29e..b662f9223 100644 --- a/pio-tools/post_esp32.py +++ b/pio-tools/post_esp32.py @@ -38,24 +38,26 @@ from SCons.Script import COMMAND_LINE_TARGETS sys.path.append(join(platform.get_package_dir("tool-esptoolpy"))) import esptool +config = env.GetProjectConfig() variants_dir = env.BoardConfig().get("build.variants_dir", "") variant = env.BoardConfig().get("build.variant", "") sections = env.subst(env.get("FLASH_EXTRA_IMAGES")) chip = env.get("BOARD_MCU") mcu_build_variant = env.BoardConfig().get("build.variant", "").lower() +flag_custom_sdkconfig = config.has_option("env:"+env["PIOENV"], "custom_sdkconfig") # Copy safeboots firmwares in place when running in Github github_actions = os.getenv('GITHUB_ACTIONS') extra_flags = ''.join([element.replace("-D", " ") for element in env.BoardConfig().get("build.extra_flags", "")]) build_flags = ''.join([element.replace("-D", " ") for element in env.GetProjectOption("build_flags")]) -if "CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags: +if ("CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags) and flag_custom_sdkconfig == False: FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-solo1") if github_actions and os.path.exists("./firmware/firmware"): shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-solo1/variants/tasmota") if variants_dir: shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) -elif "CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags: +elif ("CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags) and flag_custom_sdkconfig == False: FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-ITEAD") if github_actions and os.path.exists("./firmware/firmware"): shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-ITEAD/variants/tasmota") @@ -129,7 +131,7 @@ def patch_partitions_bin(size_string): def esp32_create_chip_string(chip): tasmota_platform_org = env.subst("$BUILD_DIR").split(os.path.sep)[-1] tasmota_platform = tasmota_platform_org.split('-')[0] - if ("CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags) and "tasmota32-safeboot" not in tasmota_platform_org and "tasmota32solo1" not in tasmota_platform_org: + if ("CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags) and "tasmota32-safeboot" not in tasmota_platform_org and "tasmota32solo1" not in tasmota_platform_org and flag_custom_sdkconfig == False: print(Fore.YELLOW + "Unexpected naming convention in this build environment:" + Fore.RED, tasmota_platform_org) print(Fore.YELLOW + "Expected build environment name like " + Fore.GREEN + "'tasmota32solo1-whatever-you-want'") print(Fore.YELLOW + "Please correct your actual build environment, to avoid undefined behavior in build process!!") From ef3c061ecf7b830f0aaed4779c945c11065c7e1a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:00:00 +0100 Subject: [PATCH 054/205] fix github actions copy error in some cases the folder already exists. Do not abort copy. --- pio-tools/post_esp32.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py index b662f9223..5fe75bf2b 100644 --- a/pio-tools/post_esp32.py +++ b/pio-tools/post_esp32.py @@ -54,19 +54,19 @@ build_flags = ''.join([element.replace("-D", " ") for element in env.GetProjectO if ("CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags) and flag_custom_sdkconfig == False: FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-solo1") if github_actions and os.path.exists("./firmware/firmware"): - shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-solo1/variants/tasmota") + shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-solo1/variants/tasmota", dirs_exist_ok=True) if variants_dir: shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) elif ("CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags) and flag_custom_sdkconfig == False: FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-ITEAD") if github_actions and os.path.exists("./firmware/firmware"): - shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-ITEAD/variants/tasmota") + shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-ITEAD/variants/tasmota", dirs_exist_ok=True) if variants_dir: shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) else: FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") if github_actions and os.path.exists("./firmware/firmware"): - shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduinoespressif32/variants/tasmota") + shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduinoespressif32/variants/tasmota", dirs_exist_ok=True) if variants_dir: shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) From 27db2634932df84e7be7353103c7b42a872abe31 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Mon, 28 Oct 2024 14:04:17 +0100 Subject: [PATCH 055/205] New feature Auto Clear Remote Temp for MiElHVAC (#22370) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes * New feature Outdoor Temperature for MiElHVAC * Add Outdoor Temperature * New feature Compressor Frequency for MiElHVAC * Added Outdoor Temperature * Renamed internal properties due typo operating and oprating to operation * New feature Auto Clear Remote Temp for MiElHVAC * This PR add auto clear remote temperature function * This funcion is call on first run and after 10 sec the remote temperature stop refresh its value * Send manually Clear command is also available * change function name, small corrections * added auto clear time configurable using cmnd --- .../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index 658796102..89de524cc 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -44,11 +44,15 @@ #define D_CMND_MIEL_HVAC_SETAIRDIRECTION "HVACSetAirDirection" #define D_CMND_MIEL_HVAC_SETPROHIBIT "HVACSetProhibit" #define D_CMND_MIEL_HVAC_REMOTETEMP "HVACRemoteTemp" +#define D_CMND_MIEL_HVAC_REMOTETEMP_AUTO_CLEAR_TIME "HVACRemoteTempClearTime" #include /* from hvac */ bool temp_type = false; +bool remotetemp_clear = true; +unsigned long remotetemp_auto_clear_time = 10000; +unsigned long remotetemp_last_call_time = 0; struct miel_hvac_header { uint8_t start; @@ -944,6 +948,39 @@ miel_hvac_remotetemp_degc2old(long degc) MIEL_HVAC_REMOTETEMP_OLD_FACTOR); } +static void +miel_hvac_auto_clear_remotetemp(void) +{ + struct miel_hvac_softc *sc = miel_hvac_sc; + struct miel_hvac_msg_remotetemp *rt = &sc->sc_remotetemp; + uint8_t control = MIEL_HVAC_REMOTETEMP_CLR; + long degc = 0; + + memset(rt, 0, sizeof(*rt)); + rt->seven = 0x7; + rt->control = control; + rt->temp_old = miel_hvac_remotetemp_degc2old(degc); + rt->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; + + remotetemp_clear = false; +} + +static void +miel_hvac_cmnd_remotetemp_auto_clear_time(void) +{ + if (XdrvMailbox.data_len == 0) + return; + + unsigned long clear_time = strtoul(XdrvMailbox.data, nullptr, 10); + if (clear_time == 0) { + miel_hvac_respond_unsupported(); + return; + } + remotetemp_auto_clear_time = clear_time; + + ResponseCmndNumber(remotetemp_auto_clear_time); +} + static void miel_hvac_cmnd_remotetemp(void) { @@ -960,6 +997,8 @@ miel_hvac_cmnd_remotetemp(void) degc = 0; ResponseCmndChar_P("clear"); + remotetemp_clear = false; + remotetemp_last_call_time = 0; } else { degc = strtol(XdrvMailbox.data, nullptr, 0); @@ -970,6 +1009,8 @@ miel_hvac_cmnd_remotetemp(void) degc = MIEL_HVAC_REMOTETEMP_MAX; ResponseCmndNumber(degc); + remotetemp_clear = true; + remotetemp_last_call_time = millis(); } memset(rt, 0, sizeof(*rt)); @@ -1539,6 +1580,7 @@ static const char miel_hvac_cmnd_names[] PROGMEM = "|" D_CMND_MIEL_HVAC_SETAIRDIRECTION "|" D_CMND_MIEL_HVAC_SETPROHIBIT "|" D_CMND_MIEL_HVAC_REMOTETEMP + "|" D_CMND_MIEL_HVAC_REMOTETEMP_AUTO_CLEAR_TIME #ifdef MIEL_HVAC_DEBUG "|" "HVACRequest" #endif @@ -1554,6 +1596,7 @@ static void (*const miel_hvac_cmnds[])(void) PROGMEM = { &miel_hvac_cmnd_setairdirection, &miel_hvac_cmnd_setprohibit, &miel_hvac_cmnd_remotetemp, + &miel_hvac_cmnd_remotetemp_auto_clear_time, #ifdef MIEL_HVAC_DEBUG &miel_hvac_cmnd_request, #endif @@ -1592,6 +1635,9 @@ bool Xdrv44(uint32_t function) { case FUNC_EVERY_100_MSECOND: case FUNC_EVERY_200_MSECOND: case FUNC_EVERY_SECOND: + if (remotetemp_clear && ((millis() - remotetemp_last_call_time) > remotetemp_auto_clear_time || remotetemp_last_call_time == 0)) { + miel_hvac_auto_clear_remotetemp(); + } break; case FUNC_JSON_APPEND: From fc0dc5dfec4f84657b3c6e47d22b65ec43e2e50f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:12:44 +0100 Subject: [PATCH 056/205] Update changelogs --- CHANGELOG.md | 1 + RELEASENOTES.md | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 233df30c0..1585e77bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - Support for US AQI and EPA AQI in PMS5003x sensors (#22294) - HLK-LD2410 Engineering mode (#21880) - Support for HLK-LD2410S 24GHz smart wave motion sensor (#22253) +- Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC (#22370) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 964d29c98..8ec8e9821 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -121,13 +121,14 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliGroup` to add gear to groups - DALI command `DaliTarget` to set light control broadcast, group number or gear number - DALI inverted signal configuration using GPIO DALI RX_i/TX_i -- Support for Shelly DALI Dimmer Gen3 (See tips and template in file xdrv_75_dali.ino) +- Support for Shelly DALI Dimmer Gen3 - Support for HLK-LD2410S 24GHz smart wave motion sensor [#22253](https://github.com/arendst/Tasmota/issues/22253) - Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) - HLK-LD2410 Engineering mode [#21880](https://github.com/arendst/Tasmota/issues/21880) - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) +- Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC [#22370](https://github.com/arendst/Tasmota/issues/22370) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) - HASPmota `haspmota.get_pages()` to get the sorted list of pages [#22358](https://github.com/arendst/Tasmota/issues/22358) From 18bfda50abc593ba52fd2426a215517734ea0c39 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Tue, 29 Oct 2024 08:25:44 +0100 Subject: [PATCH 057/205] Improvements to remote temp, auto clear time for MiElHVAC (#22379) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes * New feature Outdoor Temperature for MiElHVAC * Add Outdoor Temperature * New feature Compressor Frequency for MiElHVAC * Added Outdoor Temperature * Renamed internal properties due typo operating and oprating to operation * New feature Auto Clear Remote Temp for MiElHVAC * This PR add auto clear remote temperature function * This funcion is call on first run and after 10 sec the remote temperature stop refresh its value * Send manually Clear command is also available * change function name, small corrections * added auto clear time configurable using cmnd * Improvements to remote temp, auto clear time for MiElHVAC * Added min = 1000ms and max 600000ms limit to remotetemp auto clear time function * Changed function name to use sam format as other * Added RemoteTemperatureSensor to the sensor * more improvements to auto clear time * Changed RemoteTemperatureSensor to RemoteTemperatureSensorState * Added RemoteTemperatureSensorAutoClearTime to the sensor output --- .../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index 89de524cc..429e026f9 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -949,7 +949,7 @@ miel_hvac_remotetemp_degc2old(long degc) } static void -miel_hvac_auto_clear_remotetemp(void) +miel_hvac_remotetemp_auto_clear(void) { struct miel_hvac_softc *sc = miel_hvac_sc; struct miel_hvac_msg_remotetemp *rt = &sc->sc_remotetemp; @@ -972,7 +972,7 @@ miel_hvac_cmnd_remotetemp_auto_clear_time(void) return; unsigned long clear_time = strtoul(XdrvMailbox.data, nullptr, 10); - if (clear_time == 0) { + if (clear_time < 1000 || clear_time > 600000) { miel_hvac_respond_unsupported(); return; } @@ -997,7 +997,6 @@ miel_hvac_cmnd_remotetemp(void) degc = 0; ResponseCmndChar_P("clear"); - remotetemp_clear = false; remotetemp_last_call_time = 0; } else { degc = strtol(XdrvMailbox.data, nullptr, 0); @@ -1009,7 +1008,6 @@ miel_hvac_cmnd_remotetemp(void) degc = MIEL_HVAC_REMOTETEMP_MAX; ResponseCmndNumber(degc); - remotetemp_clear = true; remotetemp_last_call_time = millis(); } @@ -1027,6 +1025,8 @@ miel_hvac_cmnd_remotetemp(void) rt->temp_old = miel_hvac_remotetemp_degc2old(degc); rt->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; + + remotetemp_clear = control == MIEL_HVAC_REMOTETEMP_SET ? true : false; } #ifdef MIEL_HVAC_DEBUG @@ -1406,6 +1406,14 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) ResponseAppend_P(PSTR(",\"Temperature\":\"%s\""), room_temp); + ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorState\":\"%s\""), + remotetemp_clear ? "ON" : "OFF"); + + char remotetempautocleartime[33]; + ultoa(remotetemp_auto_clear_time, remotetempautocleartime, 10); + ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorAutoClearTime\":\"%s\""), + remotetempautocleartime); + if(rt->outdoortemp > 1) { char outdoor_temp[33]; float temp = miel_hvac_outdoortemp2deg(rt->outdoortemp); @@ -1636,7 +1644,7 @@ bool Xdrv44(uint32_t function) { case FUNC_EVERY_200_MSECOND: case FUNC_EVERY_SECOND: if (remotetemp_clear && ((millis() - remotetemp_last_call_time) > remotetemp_auto_clear_time || remotetemp_last_call_time == 0)) { - miel_hvac_auto_clear_remotetemp(); + miel_hvac_remotetemp_auto_clear(); } break; From 2925836a9c4566007cda65bc6b28ea620de38ce7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 29 Oct 2024 17:09:39 +0100 Subject: [PATCH 058/205] Add command ``SetOption161 1`` to disable web page slider updates by commands A long standing wish is fullfilled; GUI sliders can now be updated by commands and background runs. --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/include/tasmota_types.h | 2 +- .../xdrv_01_9_webserver.ino | 76 +++++++++++++++---- tools/decode-status.py | 2 +- 5 files changed, 66 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1585e77bc..e5d029c5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file. - HLK-LD2410 Engineering mode (#21880) - Support for HLK-LD2410S 24GHz smart wave motion sensor (#22253) - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC (#22370) +- Command ``SetOption161 1`` to disable web page slider updates by commands ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 8ec8e9821..5e6daf8d1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -116,6 +116,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ## Changelog v14.3.0.2 ### Added +- Command ``SetOption161 1`` to disable web page slider updates by commands - DALI support for short addresses (gear) and groups - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index a7a6dabc1..41b3a03fb 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -195,7 +195,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t mqtt_disable_modbus : 1; // bit 12 (v13.3.0.5) - SetOption158 - (MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead uint32_t counter_both_edges : 1; // bit 13 (v13.3.0.5) - SetOption159 - (Counter) Enable counting on both rising and falling edge (1) uint32_t ld2410_use_pin : 1; // bit 14 (v14.3.0.2) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1) - uint32_t spare15 : 1; // bit 15 + uint32_t disable_slider_updates : 1; // bit 15 (v14.3.0.2) - SetOption161 - (Light) Disable slider updates (1) uint32_t spare16 : 1; // bit 16 uint32_t spare17 : 1; // bit 17 uint32_t spare18 : 1; // bit 18 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index b9837b786..0382e78a3 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -459,6 +459,7 @@ ESP8266WebServer *Webserver; struct WEB { String chunk_buffer = ""; // Could be max 2 * CHUNKED_BUFFER_SIZE uint32_t upload_size = 0; + int slider[LST_MAX]; uint16_t upload_error = 0; uint8_t state = HTTP_OFF; uint8_t upload_file_type; @@ -595,6 +596,11 @@ void StartWebserver(int type) { if (!Settings->web_refresh) { Settings->web_refresh = HTTP_REFRESH_TIME; } if (!Web.state) { + + for (uint32_t i = 0; i < LST_MAX; i++) { + Web.slider[i] = -1; + } + if (!Webserver) { Webserver = new ESP8266WebServer((HTTP_MANAGER == type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT); @@ -1152,14 +1158,14 @@ uint32_t WebDeviceColumns(void) { } #ifdef USE_LIGHT -void WebSliderColdWarm(void) -{ +void WebSliderColdWarm(void) { + Web.slider[0] = LightGetColorTemp(); WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Cold Warm PSTR("a"), // a - Unique HTML id PSTR("#eff"), PSTR("#f81"), // 6500k in RGB (White) to 2500k in RGB (Warm Yellow) - 1, // sl1 + 1, // sl1 - used for slider updates 153, 500, // Range color temperature - LightGetColorTemp(), + Web.slider[0], 't', 0); // t0 - Value id releated to lc("t0", value) and WebGetArg("t0", tmp, sizeof(tmp)); } #endif // USE_LIGHT @@ -1226,12 +1232,13 @@ void HandleRoot(void) uint8_t sat; LightGetHSB(&hue, &sat, nullptr); + Web.slider[1] = hue; WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Hue PSTR("b"), // b - Unique HTML id PSTR("#800"), PSTR("#f00 5%,#ff0 20%,#0f0 35%,#0ff 50%,#00f 65%,#f0f 80%,#f00 95%,#800"), // Hue colors - 2, // sl2 - Unique range HTML id - Used as source for Saturation end color + 2, // sl2 - Unique range HTML id - Used as source for Saturation end color and slider updates 0, 359, // Range valid Hue - hue, + Web.slider[1], 'h', 0); // h0 - Value id uint8_t dcolor = changeUIntScale(Settings->light_dimmer, 0, 100, 0, 255); @@ -1241,33 +1248,36 @@ void HandleRoot(void) HsToRgb(hue, 255, &red, &green, &blue); snprintf_P(stemp, sizeof(stemp), PSTR("#%02X%02X%02X"), red, green, blue); // Saturation end color + Web.slider[2] = changeUIntScale(sat, 0, 255, 0, 100); WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Saturation PSTR("s"), // s - Unique HTML id related to eb('s').style.background='linear-gradient(to right,rgb('+sl+'%%,'+sl+'%%,'+sl+'%%),hsl('+eb('sl2').value+',100%%,50%%))'; scolor, stemp, // Brightness to max current color - 3, // sl3 - Unique range HTML id - Not used + 3, // sl3 - Unique range HTML id - Used for slider updates 0, 100, // Range 0 to 100% - changeUIntScale(sat, 0, 255, 0, 100), + Web.slider[2], 'n', 0); // n0 - Value id } + Web.slider[3] = Settings->light_dimmer; WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Brightness - Black to White PSTR("c"), // c - Unique HTML id PSTR("#000"), PSTR("#fff"), // Black to White - 4, // sl4 - Unique range HTML id - Used as source for Saturation begin color + 4, // sl4 - Unique range HTML id - Used as source for Saturation begin color and slider updates Settings->flag3.slider_dimmer_stay_on, 100, // Range 0/1 to 100% (SetOption77 - Do not power off if slider moved to far left) - Settings->light_dimmer, + Web.slider[3], 'd', 0); // d0 - Value id is related to lc("d0", value) and WebGetArg("d0", tmp, sizeof(tmp)); if (split_white) { // SetOption37 128 if (LST_RGBCW == light_subtype) { WebSliderColdWarm(); } + Web.slider[4] = LightGetDimmer(2); WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // White brightness - Black to White PSTR("f"), // f - Unique HTML id PSTR("#000"), PSTR("#fff"), // Black to White - 5, // sl5 - Unique range HTML id - Not used + 5, // sl5 - Unique range HTML id - Used for slider updates Settings->flag3.slider_dimmer_stay_on, 100, // Range 0/1 to 100% (SetOption77 - Do not power off if slider moved to far left) - LightGetDimmer(2), + Web.slider[4], 'w', 0); // w0 - Value id is related to lc("w0", value) and WebGetArg("w0", tmp, sizeof(tmp)); } } else { // Settings->flag3.pwm_multi_channels - SetOption68 1 - Enable multi-channels PWM instead of Color PWM @@ -1276,12 +1286,13 @@ void HandleRoot(void) for (uint32_t i = 0; i < pwm_channels; i++) { stemp[1]++; // e1 to e5 - Make unique ids + Web.slider[i] = changeUIntScale(Settings->light_color[i], 0, 255, 0, 100); WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Channel brightness - Black to White stemp, // e1 to e5 - Unique HTML id PSTR("#000"), PSTR("#fff"), // Black to White - i+1, // sl1 to sl5 - Unique range HTML id - Not used + i+1, // sl1 to sl5 - Unique range HTML id - Used for slider updates 1, 100, // Range 1 to 100% - changeUIntScale(Settings->light_color[i], 0, 255, 0, 100), + Web.slider[i], 'e', i+1); // e1 to e5 - Value id } } // Settings->flag3.pwm_multi_channels @@ -1493,6 +1504,43 @@ bool HandleRootStatusRefresh(void) WSContentBegin(200, CT_HTML); #endif // USE_WEB_SSE +#ifdef USE_LIGHT + if (!Settings->flag6.disable_slider_updates) { // SetOption161 0 - (Light) Disable slider updates (1) + uint16_t hue; + uint8_t sat; + int current_value = -1; + for (uint32_t i = 0; i < LST_MAX; i++) { + if (Web.slider[i] != -1) { + if (!Settings->flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM + if (0 == i) { + current_value = LightGetColorTemp(); + } + else if (1 == i) { + LightGetHSB(&hue, &sat, nullptr); + current_value = hue; + } + else if (2 == i) { + current_value = changeUIntScale(sat, 0, 255, 0, 100); + } + else if (3 == i) { + current_value = Settings->light_dimmer; + } + else if (4 == i) { + current_value = LightGetDimmer(2); + } + } else { + current_value = changeUIntScale(Settings->light_color[i], 0, 255, 0, 100); + } + if (current_value != Web.slider[i]) { + Web.slider[i] = current_value; + // https://stackoverflow.com/questions/4057236/how-to-add-onload-event-to-a-div-element + WSContentSend_P(PSTR(""), i +1, current_value); + } + } + } + } +#endif // USE_LIGHT + WSContentSend_P(PSTR("{t}")); // WSContentSeparator(3); // Reset seperator to ignore previous outputs if (Settings->web_time_end) { diff --git a/tools/decode-status.py b/tools/decode-status.py index 87d71125b..116c09a95 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -216,7 +216,7 @@ a_setoption = [[ "(MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead", "(Counter) Enable counting on both rising and falling edge (1)", "(LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1)", - "", + "(Light) Disable slider updates by commands (1)", "","","","", "","","","", "","","","", From 2669cd35cf9c2962ab7da446f396bf865243b989 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Tue, 29 Oct 2024 17:21:35 +0100 Subject: [PATCH 059/205] Alexa Hue with multiple devices (#22383) --- CHANGELOG.md | 1 + tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino | 23 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5d029c5f..60151a13d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 (#22367) +- Alexa Hue with multiple devices ### Removed - DALI inverted signal configuration using compile time defines diff --git a/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino b/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino index cc8f0f421..327f92919 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino @@ -415,14 +415,31 @@ const char HueConfigResponse_JSON[] PROGMEM = "\x3D\xA7\xB3\xAC\x6B\x3D\x87\x99\ /********************************************************************************************/ +// Since Oct 2024, Alexa does not distinguish anymore if the only the last 2 digits differ after '-' +// Ex: 78:e3:6d:09:1d:a4:00:11-01 +// 78:e3:6d:09:1d:a4:00:11-02 +// 78:e3:6d:09:1d:a4:00:11-03 +// are mixed up in the Alexa app +// +// We now change the encoding like this: +// 78:e3:6d:09:1d:a4:XX:YY-01 +// where XX is the high 8 bits of id (unchanged) and YY is the low 8 bits xor 0x10 (so default `1` becomes `0x11`) +// if the endpoint is not zero, XOR the second byte (rare case) String GetHueDeviceId(uint16_t id, uint8_t ep = 0) { char s[32]; String deviceid = WiFiHelper::macAddress(); deviceid.toLowerCase(); - if (0x11 == ep) { ep = 0xFE; } // avoid collision with 0x11 which is used as default for `0` - if (0 == ep) { ep = 0x11; } // if ep is zero, revert to original value - snprintf(s, sizeof(s), "%s:%02x:%02X-%02x", deviceid.c_str(), (id >> 8) & 0xFF, ep, id & 0xFF); + snprintf(s, sizeof(s), "%s:%02x:%02X-01", deviceid.c_str(), (id >> 8) & 0xFF, (id & 0xFF) ^ 0x10); + + if (ep != 0 && ep != 1) { + uint32_t mac2 = strtol(&s[3], NULL, 16); + mac2 ^= ep; + char mac2_s[4]; + snprintf(mac2_s, sizeof(mac2_s), "%02x", mac2); + s[3] = mac2_s[0]; + s[4] = mac2_s[1]; + } return String(s); // 5c:cf:7f:13:9f:3d:00:11-01 } From ccfbdd50e00b31efea6e3d249d2f14b65637deed Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 29 Oct 2024 17:27:14 +0100 Subject: [PATCH 060/205] Update changelogs --- CHANGELOG.md | 2 +- RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60151a13d..343b8a7b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 (#22367) -- Alexa Hue with multiple devices +- Alexa Hue with multiple devices (#22383) ### Removed - DALI inverted signal configuration using compile time defines diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5e6daf8d1..210e98e12 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -144,6 +144,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed +- Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 [#22367](https://github.com/arendst/Tasmota/issues/22367) From 79a7c71145a8151d8c4f54ac1b6fe0a3b0d1a1c2 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:31:56 +0100 Subject: [PATCH 061/205] Tasmota Platform 2024.11.30 / Arduino 3.1.0.241030 / IDF 5.3.1.241024 (#22384) * Platform 2024.11.30 * Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- platformio_tasmota32.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4d1fe4601..62ccb0b74 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.8 - - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241023 + - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241030 - [ ] 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/platformio_tasmota32.ini b/platformio_tasmota32.ini index 9a5d99ef1..35472e182 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -80,7 +80,7 @@ lib_ignore = ${esp32_defaults.lib_ignore} ccronexpr [core32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.10.31/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.11.30/platform-espressif32.zip platform_packages = build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} From 3f4b2331eeb3260414b028a9ae7a2b57e370cf35 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 30 Oct 2024 15:30:31 +0100 Subject: [PATCH 062/205] Bump version v14.3.0.3 - Change ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) - Fix ESP32 Arduino Core IPv6 zones used by Matter (#22378) --- CHANGELOG.md | 17 ++++++++++++++--- RELEASENOTES.md | 5 +++-- tasmota/include/tasmota_version.h | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 343b8a7b0..9edc921dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,20 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.3.0.2] +## [14.3.0.3] +### Added + +### Breaking Changed + +### Changed +- ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) + +### Fixed +- ESP32 Arduino Core IPv6 zones used by Matter (#22378) + +### Removed + +## [14.3.0.2] 20241030 ### Added - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups @@ -21,8 +34,6 @@ All notable changes to this project will be documented in this file. - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC (#22370) - Command ``SetOption161 1`` to disable web page slider updates by commands -### Breaking Changed - ### Changed - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 210e98e12..e4ecc9f9e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -114,7 +114,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.3.0.2 +## Changelog v14.3.0.3 ### Added - Command ``SetOption161 1`` to disable web page slider updates by commands - DALI support for short addresses (gear) and groups @@ -137,7 +137,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Breaking Changed ### Changed -- ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241023 [#22351](https://github.com/arendst/Tasmota/issues/22351) +- ESP32 Platform from 2024.09.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241030 and IDF to 5.3.1.241024 [#22384](https://github.com/arendst/Tasmota/issues/22384) - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default - Shutter optimized behavior to publish shutter data with sensor request [#22353](https://github.com/arendst/Tasmota/issues/22353) @@ -147,5 +147,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 [#22367](https://github.com/arendst/Tasmota/issues/22367) +- ESP32 Arduino Core IPv6 zones used by Matter [#22378](https://github.com/arendst/Tasmota/issues/22378) ### Removed diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 3813e4d07..fe63d03c4 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E030002; // 14.3.0.2 +const uint32_t TASMOTA_VERSION = 0x0E030003; // 14.3.0.3 #endif // _TASMOTA_VERSION_H_ From 0ba0b8dada94c1a03a29124d5520bda3043c0915 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Wed, 30 Oct 2024 19:50:43 +0100 Subject: [PATCH 063/205] ESP32 LVGL library from v9.2.0 to v9.2.2 (#22385) --- CHANGELOG.md | 1 + .../generate/LVGL_API_Reference.md | 1 + .../generate/be_lv_c_mapping.h | 1 + .../lv_binding_berry/mapping/lv_funcs.h | 11 +-- .../lv_binding_berry/tools/convert.py | 3 +- lib/libesp32_lvgl/lvgl/library.json | 2 +- lib/libesp32_lvgl/lvgl/library.properties | 2 +- lib/libesp32_lvgl/lvgl/lv_conf_template.h | 22 ++++- lib/libesp32_lvgl/lvgl/lv_version.h | 2 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj.c | 2 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c | 2 +- .../lvgl/src/core/lv_obj_property.c | 10 +-- .../lvgl/src/core/lv_obj_style.c | 3 + lib/libesp32_lvgl/lvgl/src/core/lv_refr.c | 2 +- .../lvgl/src/display/lv_display_private.h | 3 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c | 38 ++++++++- lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c | 12 ++- lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h | 7 +- .../lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c | 8 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp.c | 30 ++++--- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp.h | 13 ++- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c | 2 + .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c | 2 + .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c | 2 + .../lvgl/src/draw/nxp/pxp/lv_pxp_cfg.c | 6 +- .../lvgl/src/draw/nxp/pxp/lv_pxp_cfg.h | 6 +- .../lvgl/src/draw/nxp/pxp/lv_pxp_osa.c | 6 +- .../lvgl/src/draw/nxp/pxp/lv_pxp_osa.h | 6 +- .../lvgl/src/draw/nxp/pxp/lv_pxp_utils.c | 6 +- .../lvgl/src/draw/nxp/pxp/lv_pxp_utils.h | 6 +- .../src/draw/nxp/vglite/lv_draw_buf_vglite.c | 22 ++++- .../lvgl/src/draw/nxp/vglite/lv_draw_vglite.c | 21 ++--- .../draw/nxp/vglite/lv_draw_vglite_triangle.c | 4 +- .../src/draw/sw/lv_draw_sw_mask_private.h | 4 + .../lvgl/src/draw/sw/lv_draw_sw_transform.c | 4 +- .../lvgl/src/draw/vg_lite/lv_draw_vg_lite.c | 4 +- .../src/draw/vg_lite/lv_draw_vg_lite_arc.c | 10 +-- .../src/draw/vg_lite/lv_draw_vg_lite_border.c | 4 +- .../src/draw/vg_lite/lv_draw_vg_lite_fill.c | 17 ++-- .../src/draw/vg_lite/lv_draw_vg_lite_img.c | 56 ++++++++----- .../src/draw/vg_lite/lv_draw_vg_lite_label.c | 13 +-- .../src/draw/vg_lite/lv_draw_vg_lite_line.c | 4 +- .../draw/vg_lite/lv_draw_vg_lite_mask_rect.c | 13 +-- .../draw/vg_lite/lv_draw_vg_lite_triangle.c | 4 +- .../src/draw/vg_lite/lv_draw_vg_lite_vector.c | 12 ++- .../lvgl/src/draw/vg_lite/lv_vg_lite_path.c | 22 +++++ .../lvgl/src/draw/vg_lite/lv_vg_lite_path.h | 2 + .../lvgl/src/draw/vg_lite/lv_vg_lite_utils.c | 25 ++---- .../lvgl/src/draw/vg_lite/lv_vg_lite_utils.h | 8 +- .../src/drivers/glfw/lv_opengles_texture.c | 2 +- .../drivers/libinput/lv_libinput_private.h | 4 + .../lvgl/src/drivers/libinput/lv_xkb.h | 1 + .../lvgl/src/drivers/nuttx/lv_nuttx_lcd.c | 4 +- .../lvgl/src/drivers/sdl/lv_sdl_window.c | 4 +- lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c | 5 -- lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c | 30 ++++++- lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c | 30 +++++++ lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h | 19 +++++ lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h | 52 ++++++++++-- lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h | 10 +++ lib/libesp32_lvgl/lvgl/src/lv_init.c | 14 +++- lib/libesp32_lvgl/lvgl/src/lvgl_private.h | 1 - lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c | 2 +- .../lvgl/src/misc/lv_bidi_private.h | 3 + lib/libesp32_lvgl/lvgl/src/misc/lv_color.c | 1 + lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h | 6 ++ .../lvgl/src/misc/lv_fs_private.h | 6 -- lib/libesp32_lvgl/lvgl/src/misc/lv_types.h | 4 - lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c | 84 ++++++++++++------- lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h | 10 +-- .../lvgl/src/others/ime/lv_ime_pinyin.c | 5 +- .../lvgl/src/others/sysmon/lv_sysmon.c | 4 +- .../lvgl/src/widgets/animimage/lv_animimage.c | 7 ++ .../lvgl/src/widgets/animimage/lv_animimage.h | 8 ++ .../lvgl/src/widgets/arc/lv_arc.c | 32 ++++++- .../lvgl/src/widgets/bar/lv_bar_private.h | 4 +- .../widgets/buttonmatrix/lv_buttonmatrix.c | 14 ++-- .../widgets/buttonmatrix/lv_buttonmatrix.h | 4 +- .../buttonmatrix/lv_buttonmatrix_private.h | 2 +- .../widgets/calendar/lv_calendar_chinese.c | 31 ++++--- .../widgets/calendar/lv_calendar_chinese.h | 15 +++- .../lvgl/src/widgets/dropdown/lv_dropdown.c | 30 +++---- .../lvgl/src/widgets/image/lv_image.c | 13 ++- .../lvgl/src/widgets/keyboard/lv_keyboard.c | 26 +++--- .../lvgl/src/widgets/keyboard/lv_keyboard.h | 4 +- .../lvgl/src/widgets/roller/lv_roller.c | 10 ++- .../lvgl/src/widgets/span/lv_span.c | 2 +- .../lvgl/src/widgets/textarea/lv_textarea.c | 7 +- tasmota/lvgl_berry/tasmota_lv_conf.h | 22 ++++- 89 files changed, 675 insertions(+), 323 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9edc921dd..c7d63ad60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. ### Changed - ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) +- ESP32 LVGL library from v9.2.0 to v9.2.2 ### Fixed - ESP32 Arduino Core IPv6 zones used by Matter (#22378) diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/LVGL_API_Reference.md b/lib/libesp32_lvgl/lv_binding_berry/generate/LVGL_API_Reference.md index 8a88aab87..e89139c74 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/generate/LVGL_API_Reference.md +++ b/lib/libesp32_lvgl/lv_binding_berry/generate/LVGL_API_Reference.md @@ -1501,6 +1501,7 @@ set_button_text|lv.obj, string||[lv_list_set_button_text](https://docs.lvgl.io/9 Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- +get_anim||lv.anim|[lv_animimg_get_anim](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_anim) get_duration||int|[lv_animimg_get_duration](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_duration) get_repeat_count||int|[lv_animimg_get_repeat_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_repeat_count) get_src_count||int|[lv_animimg_get_src_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_src_count) diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h index 8d117ef29..f12c88315 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h +++ b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h @@ -818,6 +818,7 @@ const be_ntv_func_def_t lv_timer_func[] = { /* `lv_animimg` methods */ #ifdef BE_LV_WIDGET_ANIMIMG const be_ntv_func_def_t lv_animimg_func[] = { + { "get_anim", { (const void*) &lv_animimg_get_anim, "lv.anim", "(lv.obj)" } }, { "get_duration", { (const void*) &lv_animimg_get_duration, "i", "(lv.obj)" } }, { "get_repeat_count", { (const void*) &lv_animimg_get_repeat_count, "i", "(lv.obj)" } }, { "get_src_count", { (const void*) &lv_animimg_get_src_count, "i", "(lv.obj)" } }, diff --git a/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h b/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h index 91d1eca59..41c6cb08f 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h +++ b/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h @@ -1013,6 +1013,7 @@ const void ** lv_animimg_get_src(lv_obj_t * img) uint8_t lv_animimg_get_src_count(lv_obj_t * img) uint32_t lv_animimg_get_duration(lv_obj_t * img) uint32_t lv_animimg_get_repeat_count(lv_obj_t * img) +lv_anim_t * lv_animimg_get_anim(lv_obj_t * img) // ../../lvgl/src/widgets/arc/lv_arc.h lv_obj_t * lv_arc_create(lv_obj_t * parent) @@ -1061,7 +1062,7 @@ lv_obj_t * lv_button_create(lv_obj_t * parent) // ../../lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent) -void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[]) +void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[]) void lv_buttonmatrix_set_ctrl_map(lv_obj_t * obj, const lv_buttonmatrix_ctrl_t ctrl_map[]) void lv_buttonmatrix_set_selected_button(lv_obj_t * obj, uint32_t btn_id) void lv_buttonmatrix_set_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl) @@ -1070,7 +1071,7 @@ void lv_buttonmatrix_set_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t void lv_buttonmatrix_clear_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t ctrl) void lv_buttonmatrix_set_button_width(lv_obj_t * obj, uint32_t btn_id, uint32_t width) void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en) -const char ** lv_buttonmatrix_get_map(const lv_obj_t * obj) +const char * const * lv_buttonmatrix_get_map(const lv_obj_t * obj) uint32_t lv_buttonmatrix_get_selected_button(const lv_obj_t * obj) const char * lv_buttonmatrix_get_button_text(const lv_obj_t * obj, uint32_t btn_id) bool lv_buttonmatrix_has_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl) @@ -1092,7 +1093,7 @@ lv_result_t lv_calendar_get_pressed_date(const lv_obj_t * calendar, lv_calendar_ // ../../lvgl/src/widgets/calendar/lv_calendar_chinese.h void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en) const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian) -lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian) +void lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian_time, lv_calendar_chinese_t * chinese_time) // ../../lvgl/src/widgets/calendar/lv_calendar_header_arrow.h lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent) @@ -1220,11 +1221,11 @@ lv_obj_t * lv_keyboard_create(lv_obj_t * parent) void lv_keyboard_set_textarea(lv_obj_t * kb, lv_obj_t * ta) void lv_keyboard_set_mode(lv_obj_t * kb, lv_keyboard_mode_t mode) void lv_keyboard_set_popovers(lv_obj_t * kb, bool en) -void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * map[], const lv_buttonmatrix_ctrl_t ctrl_map[]) +void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * const map[], const lv_buttonmatrix_ctrl_t ctrl_map[]) lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * kb) lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb) bool lv_keyboard_get_popovers(const lv_obj_t * obj) -const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) +const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb) uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj) const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id) diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py index 239390126..9558c1df0 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py +++ b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py @@ -407,7 +407,7 @@ class type_mapper_class: "lv_roller_mode_t": "i", "lv_table_cell_ctrl_t": "i", - "lv_calendar_chinese_t": "c", + # "lv_calendar_chinese_t": "c", # adding ad-hoc colorwheel from LVGL8 to LVGL9 "lv_colorwheel_mode_t": "i", @@ -459,6 +459,7 @@ class type_mapper_class: # "char **": "lv_str_arr", # treat as a simple pointer, decoding needs to be done at Berry level "constchar **": "c", # treat as a simple pointer, decoding needs to be done at Berry level "void * []": "c", # treat as a simple pointer, decoding needs to be done at Berry level + "constchar * *": "c", # callbacks "lv_group_focus_cb_t": "lv_group_focus_cb", diff --git a/lib/libesp32_lvgl/lvgl/library.json b/lib/libesp32_lvgl/lvgl/library.json index 370c00a6d..ccdc959dc 100644 --- a/lib/libesp32_lvgl/lvgl/library.json +++ b/lib/libesp32_lvgl/lvgl/library.json @@ -1,6 +1,6 @@ { "name": "lvgl", - "version": "9.2.0", + "version": "9.2.2", "keywords": "graphics, gui, embedded, tft, lvgl", "description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.", "repository": { diff --git a/lib/libesp32_lvgl/lvgl/library.properties b/lib/libesp32_lvgl/lvgl/library.properties index 7dbe2228e..79a170e8f 100644 --- a/lib/libesp32_lvgl/lvgl/library.properties +++ b/lib/libesp32_lvgl/lvgl/library.properties @@ -1,5 +1,5 @@ name=lvgl -version=9.2.0 +version=9.2.2 author=kisvegabor maintainer=kisvegabor,embeddedt,pete-pjb sentence=Full-featured Graphics Library for Embedded Systems diff --git a/lib/libesp32_lvgl/lvgl/lv_conf_template.h b/lib/libesp32_lvgl/lvgl/lv_conf_template.h index ab886a96b..99e4aee66 100644 --- a/lib/libesp32_lvgl/lvgl/lv_conf_template.h +++ b/lib/libesp32_lvgl/lvgl/lv_conf_template.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for v9.2.0 + * Configuration file for v9.2.2 */ /* @@ -95,6 +95,14 @@ #if LV_USE_OS == LV_OS_CUSTOM #define LV_OS_CUSTOM_INCLUDE #endif +#if LV_USE_OS == LV_OS_FREERTOS + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ + #define LV_USE_FREERTOS_TASK_NOTIFY 1 +#endif /*======================== * RENDERING CONFIGURATION @@ -205,10 +213,16 @@ #endif /* Use NXP's PXP on iMX RTxxx platforms. */ -#define LV_USE_DRAW_PXP 0 +#define LV_USE_PXP 0 -#if LV_USE_DRAW_PXP - #if LV_USE_OS +#if LV_USE_PXP + /* Use PXP for drawing.*/ + #define LV_USE_DRAW_PXP 1 + + /* Use PXP to rotate display.*/ + #define LV_USE_ROTATE_PXP 0 + + #if LV_USE_DRAW_PXP && LV_USE_OS /* Use additional draw thread for PXP processing.*/ #define LV_USE_PXP_DRAW_THREAD 1 #endif diff --git a/lib/libesp32_lvgl/lvgl/lv_version.h b/lib/libesp32_lvgl/lvgl/lv_version.h index 7e6356a66..5767c66c5 100644 --- a/lib/libesp32_lvgl/lvgl/lv_version.h +++ b/lib/libesp32_lvgl/lvgl/lv_version.h @@ -8,7 +8,7 @@ #define LVGL_VERSION_MAJOR 9 #define LVGL_VERSION_MINOR 2 -#define LVGL_VERSION_PATCH 0 +#define LVGL_VERSION_PATCH 2 #define LVGL_VERSION_INFO "" #endif /* LVGL_VERSION_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c index 9b9f56d3f..c58e95502 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c @@ -306,7 +306,7 @@ void lv_obj_add_state(lv_obj_t * obj, lv_state_t state) lv_state_t new_state = obj->state | state; if(obj->state != new_state) { - if(new_state & LV_STATE_DISABLED) { + if(new_state & ~obj->state & LV_STATE_DISABLED) { lv_indev_reset(NULL, obj); } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c index b5fd34d76..0f10d7dcc 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c @@ -1046,7 +1046,7 @@ static int32_t calc_content_width(lv_obj_t * obj) default: /* Consider other cases only if x=0 and use the width of the object. * With x!=0 circular dependency could occur. */ - if(lv_obj_get_style_y(child, 0) == 0) { + if(lv_obj_get_style_x(child, 0) == 0) { child_res_tmp = lv_area_get_width(&child->coords) + space_left; child_res_tmp += lv_obj_get_style_margin_right(child, LV_PART_MAIN); } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c index f15ee1186..405b00674 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c @@ -44,7 +44,7 @@ typedef lv_result_t (*lv_property_getter_t)(const lv_obj_t *, lv_prop_id_t, lv_p **********************/ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set); -static int32_t property_name_compare(const void * ref, const void * element); +static int property_name_compare(const void * ref, const void * element); /********************** * STATIC VARIABLES @@ -121,7 +121,7 @@ lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_ uint32_t index = LV_PROPERTY_ID_INDEX(id); if(index == LV_PROPERTY_ID_INVALID || index >= LV_PROPERTY_ID_START) { - LV_LOG_WARN("invalid style property id %d", id); + LV_LOG_WARN("invalid style property id 0x%" LV_PRIx32, id); value.id = LV_PROPERTY_ID_INVALID; value.num = 0; return value; @@ -232,7 +232,7 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * /*id matched but we got null pointer to functions*/ if(set ? prop->setter == NULL : prop->getter == NULL) { - LV_LOG_WARN("NULL %s provided, id: %d", set ? "setter" : "getter", id); + LV_LOG_WARN("NULL %s provided, id: 0x%" LV_PRIx32, set ? "setter" : "getter", id); return LV_RESULT_INVALID; } @@ -278,7 +278,7 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * break; } default: { - LV_LOG_WARN("Unknown property id: 0x%08x", prop->id); + LV_LOG_WARN("Unknown property id: 0x%08" LV_PRIx32, prop->id); return LV_RESULT_INVALID; } } @@ -289,7 +289,7 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * /*If no setter found, try base class then*/ } - LV_LOG_WARN("Unknown property id: 0x%08x", id); + LV_LOG_WARN("Unknown property id: 0x%08" LV_PRIx32, id); return LV_RESULT_INVALID; } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c index 26bc39729..06e3ffec3 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c @@ -353,6 +353,9 @@ bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, l void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value, lv_style_selector_t selector) { + /*Stop running transitions wit this property */ + trans_delete(obj, lv_obj_style_get_selector_part(selector), prop, NULL); + lv_style_t * style = get_local_style(obj, selector); if(selector == LV_PART_MAIN && lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_TRANSFORM)) { lv_obj_invalidate(obj); diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c index 13a2608e6..e91fc0059 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c @@ -355,7 +355,7 @@ void lv_display_refr_timer(lv_timer_t * tmr) /* Ensure the timer does not run again automatically. * This is done before refreshing in case refreshing invalidates something else. * However if the performance monitor is enabled keep the timer running to count the FPS.*/ -#if LV_USE_PERF_MONITOR +#if !LV_USE_PERF_MONITOR lv_timer_pause(tmr); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h b/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h index bcdc95c46..7dc9f189f 100644 --- a/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h +++ b/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h @@ -141,8 +141,7 @@ struct lv_display_t { lv_event_list_t event_list; - uint32_t sw_rotate : 1; /**< 1: use software rotation (slower)*/ - uint32_t rotation : 2; /**< Element of lv_display_rotation_t*/ + uint32_t rotation : 3; /**< Element of lv_display_rotation_t*/ lv_theme_t * theme; /**< The theme assigned to the screen*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c index 8de27efad..dbaec7028 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c @@ -179,8 +179,7 @@ void lv_draw_dispatch(void) while(disp) { lv_layer_t * layer = disp->layer_head; while(layer) { - /* If there are no tasks in the layer, skip it */ - if(layer->draw_task_head && lv_draw_dispatch_layer(disp, layer)) + if(lv_draw_dispatch_layer(disp, layer)) task_dispatched = true; layer = layer->next; } @@ -311,6 +310,41 @@ uint32_t lv_draw_get_unit_count(void) lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id) { LV_PROFILER_BEGIN; + + /* If there is only 1 draw unit the task can be consumed linearly as + * they are added in the correct order. However, it can happen that + * there is a `LV_DRAW_TASK_TYPE_LAYER` which can be blended only when + * all its tasks are ready. As other areas might be on top of that + * layer-to-blend don't skip it. Instead stop there, so that the + * draw tasks of that layer can be consumed and can be finished. + * After that this layer-to-blenf will have `LV_DRAW_TASK_STATE_QUEUED` + * so it can be blended normally.*/ + if(_draw_info.unit_cnt <= 1) { + lv_draw_task_t * t = layer->draw_task_head; + while(t) { + /*Mark unsupported draw tasks as ready as no one else will consume them*/ + if(t->state == LV_DRAW_TASK_STATE_QUEUED && + t->preferred_draw_unit_id != LV_DRAW_UNIT_NONE && + t->preferred_draw_unit_id != draw_unit_id) { + t->state = LV_DRAW_TASK_STATE_READY; + } + /*Not queued yet, leave this layer while the first task will be queued*/ + else if(t->state != LV_DRAW_TASK_STATE_QUEUED) { + t = NULL; + break; + } + /*It's a supported and queued task, process it*/ + else { + break; + } + t = t->next; + } + LV_PROFILER_END; + return t; + } + + /*Handle the case of multiply draw units*/ + /*If the first task is screen sized, there cannot be independent areas*/ if(layer->draw_task_head) { int32_t hor_res = lv_display_get_horizontal_resolution(lv_refr_get_disp_refreshing()); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c index daebe9543..a6dc29bb1 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c @@ -83,6 +83,16 @@ lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void) return &default_handlers; } +lv_draw_buf_handlers_t * lv_draw_buf_get_font_handlers(void) +{ + return &font_draw_buf_handlers; +} + +lv_draw_buf_handlers_t * lv_draw_buf_get_image_handlers(void) +{ + return &image_cache_draw_buf_handlers; +} + uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format) { return lv_draw_buf_width_to_stride_ex(&default_handlers, w, color_format); @@ -536,7 +546,7 @@ void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32 palette[index] = color; } -bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) +bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag) { return draw_buf->header.flags & flag; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h index 9cc6526e5..22b09de0a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h @@ -67,7 +67,7 @@ LV_EXPORT_CONST_INT(LV_STRIDE_AUTO); #define LV_DRAW_BUF_INIT_STATIC(name) \ do { \ lv_image_header_t * header = &name.header; \ - lv_draw_buf_init(&name, header->w, header->h, header->cf, header->stride, buf_##name, sizeof(buf_##name)); \ + lv_draw_buf_init(&name, header->w, header->h, (lv_color_format_t)header->cf, header->stride, buf_##name, sizeof(buf_##name)); \ lv_draw_buf_set_flag(&name, LV_IMAGE_FLAGS_MODIFIABLE); \ } while(0) @@ -129,6 +129,9 @@ void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers, * @return pointer to the struct of handlers */ lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void); +lv_draw_buf_handlers_t * lv_draw_buf_get_font_handlers(void); +lv_draw_buf_handlers_t * lv_draw_buf_get_image_handlers(void); + /** * Align the address of a buffer. The buffer needs to be large enough for the real data after alignment @@ -304,7 +307,7 @@ lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride); */ lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf); -bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); +bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag); void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c index e83da1ca3..9819cfc64 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c @@ -15,6 +15,7 @@ #include "lv_draw_pxp.h" +#if LV_USE_PXP #if LV_USE_DRAW_PXP #include "../../lv_draw_buf_private.h" #include "lv_pxp_cfg.h" @@ -51,8 +52,12 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * void lv_draw_buf_pxp_init_handlers(void) { lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); + lv_draw_buf_handlers_t * font_handlers = lv_draw_buf_get_font_handlers(); + lv_draw_buf_handlers_t * image_handlers = lv_draw_buf_get_image_handlers(); handlers->invalidate_cache_cb = _invalidate_cache; + font_handlers->invalidate_cache_cb = _invalidate_cache; + image_handlers->invalidate_cache_cb = _invalidate_cache; } /********************** @@ -66,7 +71,7 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * lv_color_format_t cf = header->cf; if(area->y1 == 0) { - uint16_t size = stride * lv_area_get_height(area); + uint32_t size = stride * lv_area_get_height(area); /* Invalidate full buffer. */ DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size); @@ -109,3 +114,4 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * } #endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_PXP*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.c index e606e6798..636fe4379 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.c @@ -15,7 +15,8 @@ #include "lv_draw_pxp.h" -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP #include "lv_pxp_cfg.h" #include "lv_pxp_utils.h" @@ -82,6 +83,9 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u); void lv_draw_pxp_init(void) { + lv_pxp_init(); + +#if LV_USE_DRAW_PXP lv_draw_buf_pxp_init_handlers(); lv_draw_pxp_unit_t * draw_pxp_unit = lv_draw_create_unit(sizeof(lv_draw_pxp_unit_t)); @@ -89,11 +93,10 @@ void lv_draw_pxp_init(void) draw_pxp_unit->base_unit.dispatch_cb = _pxp_dispatch; draw_pxp_unit->base_unit.delete_cb = _pxp_delete; - lv_pxp_init(); - #if LV_USE_PXP_DRAW_THREAD lv_thread_init(&draw_pxp_unit->thread, LV_THREAD_PRIO_HIGH, _pxp_render_thread_cb, 2 * 1024, draw_pxp_unit); #endif +#endif /*LV_USE_DRAW_PXP*/ } void lv_draw_pxp_deinit(void) @@ -107,19 +110,26 @@ void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width { lv_pxp_reset(); - /* convert rotation angle */ + /* Convert rotation angle + * To be in sync with CPU, the received angle is counterclockwise + * and the PXP constants are for clockwise rotation + * + * counterclockwise clockwise + * LV_DISPLAY_ROTATION_90 -> kPXP_Rotate270 + * LV_DISPLAY_ROTATION_270 -> kPXP_Rotate90 + */ pxp_rotate_degree_t pxp_rotation; switch(rotation) { case LV_DISPLAY_ROTATION_0: pxp_rotation = kPXP_Rotate0; break; - case LV_DISPLAY_ROTATION_90: + case LV_DISPLAY_ROTATION_270: pxp_rotation = kPXP_Rotate90; break; case LV_DISPLAY_ROTATION_180: pxp_rotation = kPXP_Rotate180; break; - case LV_DISPLAY_ROTATION_270: + case LV_DISPLAY_ROTATION_90: pxp_rotation = kPXP_Rotate270; break; default: @@ -159,7 +169,7 @@ void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width /********************** * STATIC FUNCTIONS **********************/ - +#if LV_USE_DRAW_PXP static inline bool _pxp_src_cf_supported(lv_color_format_t cf) { bool is_cf_supported = false; @@ -321,8 +331,7 @@ static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_PXP) return LV_DRAW_UNIT_IDLE; - void * buf = lv_draw_layer_alloc_buf(layer); - if(buf == NULL) + if(lv_draw_layer_alloc_buf(layer) == NULL) return LV_DRAW_UNIT_IDLE; t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; @@ -484,5 +493,6 @@ static void _pxp_render_thread_cb(void * ptr) LV_LOG_INFO("Exit PXP draw thread."); } #endif - #endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.h index d5e98d791..d34ad3f84 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.h @@ -22,8 +22,10 @@ extern "C" { #include "../../../lv_conf_internal.h" -#if LV_USE_DRAW_PXP -#include "../../sw/lv_draw_sw.h" +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP +#include "../../sw/lv_draw_sw_private.h" +#include "../../../misc/lv_area_private.h" /********************* * DEFINES @@ -39,8 +41,6 @@ typedef lv_draw_sw_unit_t lv_draw_pxp_unit_t; * GLOBAL PROTOTYPES **********************/ -void lv_draw_buf_pxp_init_handlers(void); - void lv_draw_pxp_init(void); void lv_draw_pxp_deinit(void); @@ -49,6 +49,9 @@ void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation, lv_color_format_t cf); +#if LV_USE_DRAW_PXP +void lv_draw_buf_pxp_init_handlers(void); + void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); @@ -62,6 +65,8 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d * MACROS **********************/ #endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c index c75de3480..33b80473c 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c @@ -15,6 +15,7 @@ #include "lv_draw_pxp.h" +#if LV_USE_PXP #if LV_USE_DRAW_PXP #include "lv_pxp_cfg.h" #include "lv_pxp_utils.h" @@ -145,3 +146,4 @@ static void _pxp_fill(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t d } #endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_PXP*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c index 08c0a8ad6..79f3790e9 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c @@ -15,6 +15,7 @@ #include "lv_draw_pxp.h" +#if LV_USE_PXP #if LV_USE_DRAW_PXP #include "lv_pxp_cfg.h" #include "lv_pxp_utils.h" @@ -363,3 +364,4 @@ static void _pxp_blit(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t d } #endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_PXP*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c index 4ee33010d..34cb285b7 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c @@ -15,6 +15,7 @@ #include "lv_draw_pxp.h" +#if LV_USE_PXP #if LV_USE_DRAW_PXP #include "../../../stdlib/lv_string.h" @@ -154,3 +155,4 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d } #endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_PXP*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_cfg.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_cfg.c index f1d796293..675c1d030 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_cfg.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_cfg.c @@ -15,7 +15,8 @@ #include "lv_pxp_cfg.h" -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP #include "lv_pxp_osa.h" /********************* @@ -88,4 +89,5 @@ void lv_pxp_wait(void) * STATIC FUNCTIONS **********************/ -#endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_cfg.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_cfg.h index b487e7ff9..67d135857 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_cfg.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_cfg.h @@ -22,7 +22,8 @@ extern "C" { #include "../../../lv_conf_internal.h" -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP #include "fsl_cache.h" #include "fsl_pxp.h" @@ -93,7 +94,8 @@ void lv_pxp_wait(void); * MACROS **********************/ -#endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.c index b573b212b..43dd8155b 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.c @@ -15,7 +15,8 @@ #include "lv_pxp_osa.h" -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP #include "lv_pxp_utils.h" #include "../../../misc/lv_log.h" #include "../../../osal/lv_os.h" @@ -183,4 +184,5 @@ static void _pxp_wait(void) #endif } -#endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.h index 371429049..5e3d6669d 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.h @@ -22,7 +22,8 @@ extern "C" { #include "../../../lv_conf_internal.h" -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP #include "lv_pxp_cfg.h" /********************* @@ -51,7 +52,8 @@ pxp_cfg_t * pxp_get_default_cfg(void); * MACROS **********************/ -#endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_utils.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_utils.c index 3940a68b5..26acf6ca9 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_utils.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_utils.c @@ -15,7 +15,8 @@ #include "lv_pxp_utils.h" -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP /********************* * DEFINES @@ -89,6 +90,7 @@ pxp_as_pixel_format_t pxp_get_as_px_format(lv_color_format_t cf) return as_px_format; } +#if LV_USE_DRAW_PXP pxp_ps_pixel_format_t pxp_get_ps_px_format(lv_color_format_t cf) { pxp_ps_pixel_format_t ps_px_format = kPXP_PsPixelFormatRGB565; @@ -143,3 +145,5 @@ bool pxp_buf_aligned(const void * buf, uint32_t stride) **********************/ #endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_utils.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_utils.h index a1f0a16c4..c9ba7bafd 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_utils.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_utils.h @@ -21,7 +21,8 @@ extern "C" { *********************/ #include "../../../lv_conf_internal.h" -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP #include "fsl_pxp.h" #include "../../../misc/lv_color.h" @@ -59,6 +60,7 @@ pxp_output_pixel_format_t pxp_get_out_px_format(lv_color_format_t cf); pxp_as_pixel_format_t pxp_get_as_px_format(lv_color_format_t cf); +#if LV_USE_DRAW_PXP pxp_ps_pixel_format_t pxp_get_ps_px_format(lv_color_format_t cf); bool pxp_buf_aligned(const void * buf, uint32_t stride); @@ -72,6 +74,8 @@ bool pxp_buf_aligned(const void * buf, uint32_t stride); **********************/ #endif /*LV_USE_DRAW_PXP*/ +#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/ +#endif /*LV_USE_PXP*/ #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_buf_vglite.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_buf_vglite.c index ae9b59a5e..85403956f 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_buf_vglite.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_buf_vglite.c @@ -35,6 +35,7 @@ **********************/ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); +static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf); /********************** * STATIC VARIABLES @@ -51,8 +52,17 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * void lv_draw_buf_vglite_init_handlers(void) { lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); + lv_draw_buf_handlers_t * font_handlers = lv_draw_buf_get_font_handlers(); + lv_draw_buf_handlers_t * image_handlers = lv_draw_buf_get_image_handlers(); handlers->invalidate_cache_cb = _invalidate_cache; + font_handlers->invalidate_cache_cb = _invalidate_cache; + image_handlers->invalidate_cache_cb = _invalidate_cache; + + handlers->width_to_stride_cb = _width_to_stride; + font_handlers->width_to_stride_cb = _width_to_stride; + image_handlers->width_to_stride_cb = _width_to_stride; + } /********************** @@ -66,7 +76,7 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * lv_color_format_t cf = header->cf; if(area->y1 == 0) { - uint16_t size = stride * lv_area_get_height(area); + uint32_t size = stride * lv_area_get_height(area); /* Invalidate full buffer. */ DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size); @@ -108,4 +118,14 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * } } +static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf) +{ + uint8_t bits_per_pixel = lv_color_format_get_bpp(cf); + uint32_t width_bits = (w * bits_per_pixel + 7) & ~7; + uint32_t width_bytes = width_bits / 8; + uint8_t align_bytes = vglite_get_stride_alignment(cf); + + return (width_bytes + align_bytes - 1) & ~(align_bytes - 1); +} + #endif /*LV_USE_DRAW_VGLITE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.c index bf9dce96e..c6fc016f4 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.c @@ -291,16 +291,14 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) if(t == NULL) return LV_DRAW_UNIT_IDLE; - if(lv_draw_get_unit_count() > 1) { - /* Let the SW unit to draw this task. */ - if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) + if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) { + /* Let the preferred known unit to draw this task. */ + if(t->preferred_draw_unit_id != LV_DRAW_UNIT_NONE) { return LV_DRAW_UNIT_IDLE; - } - else { - /* Fake unsupported tasks as ready. */ - if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) { + } + else { + /* Fake unsupported tasks as ready. */ t->state = LV_DRAW_TASK_STATE_READY; - /* Request a new dispatching as it can get a new task. */ lv_draw_dispatch_request(); @@ -308,8 +306,7 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) } } - void * buf = lv_draw_layer_alloc_buf(layer); - if(buf == NULL) + if(lv_draw_layer_alloc_buf(layer) == NULL) return LV_DRAW_UNIT_IDLE; t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; @@ -340,9 +337,13 @@ static int32_t _vglite_wait_for_finish(lv_draw_unit_t * draw_unit) lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit; draw_vglite_unit->wait_for_finish = true; + /* Signal draw unit to finish its tasks and return READY state after completion. */ if(draw_vglite_unit->inited) lv_thread_sync_signal(&draw_vglite_unit->sync); + /* Wait for finish now. */ + lv_draw_dispatch_wait_for_request(); + return 1; } #endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_triangle.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_triangle.c index 4f72f3aff..8556fdf2a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_triangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_triangle.c @@ -97,8 +97,8 @@ static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * cl tri_area.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); tri_area.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); - uint32_t width = tri_area.x2 - tri_area.x1; - uint32_t height = tri_area.y2 - tri_area.y1; + uint32_t width = lv_area_get_width(&tri_area); + uint32_t height = lv_area_get_height(&tri_area); /* Init path */ int32_t triangle_path[] = { /*VG line path*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_private.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_private.h index 44d3f87d5..aeae9b8ea 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_private.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_private.h @@ -16,6 +16,8 @@ extern "C" { #include "lv_draw_sw_mask.h" +#if LV_DRAW_SW_COMPLEX + /********************* * DEFINES *********************/ @@ -146,6 +148,8 @@ void lv_draw_sw_mask_cleanup(void); * MACROS **********************/ +#endif /*LV_DRAW_SW_COMPLEX*/ + #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_transform.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_transform.c index d4301100b..41036d430 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_transform.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_transform.c @@ -455,7 +455,7 @@ static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h dest_c32[x].alpha = (dest_c32[x].alpha * (0xFF - ys_fract)) >> 8; } else if(!lv_color32_eq(dest_c32[x], px_ver)) { - dest_c32[x].alpha = ((px_ver.alpha * ys_fract) + (dest_c32[x].alpha * (0xFF - ys_fract))) >> 8; + if(dest_c32[x].alpha) dest_c32[x].alpha = ((px_ver.alpha * ys_fract) + (dest_c32[x].alpha * (0xFF - ys_fract))) >> 8; px_ver.alpha = ys_fract; dest_c32[x] = lv_color_mix32(px_ver, dest_c32[x]); } @@ -464,7 +464,7 @@ static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h dest_c32[x].alpha = (dest_c32[x].alpha * (0xFF - xs_fract)) >> 8; } else if(!lv_color32_eq(dest_c32[x], px_hor)) { - dest_c32[x].alpha = ((px_hor.alpha * xs_fract) + (dest_c32[x].alpha * (0xFF - xs_fract))) >> 8; + if(dest_c32[x].alpha) dest_c32[x].alpha = ((px_hor.alpha * xs_fract) + (dest_c32[x].alpha * (0xFF - xs_fract))) >> 8; px_hor.alpha = xs_fract; dest_c32[x] = lv_color_mix32(px_hor, dest_c32[x]); } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.c index 145c00757..1a991ce0f 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.c @@ -114,7 +114,9 @@ static void draw_execute(lv_draw_vg_lite_unit_t * u) lv_draw_buf_set_flag(layer->draw_buf, LV_IMAGE_FLAGS_PREMULTIPLIED); vg_lite_identity(&u->global_matrix); - vg_lite_translate(-layer->buf_area.x1, -layer->buf_area.y1, &u->global_matrix); + if(layer->buf_area.x1 || layer->buf_area.y1) { + vg_lite_translate(-layer->buf_area.x1, -layer->buf_area.y1, &u->global_matrix); + } #if LV_DRAW_TRANSFORM_USE_MATRIX vg_lite_matrix_t layer_matrix; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_arc.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_arc.c index 68893c0e4..be995ceac 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_arc.c @@ -149,9 +149,7 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d lv_vg_lite_path_end(path); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); + vg_lite_matrix_t matrix = u->global_matrix; vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); @@ -174,10 +172,8 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d if(dsc->img_src) { vg_lite_buffer_t src_buf; lv_image_decoder_dsc_t decoder_dsc; - if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false)) { - vg_lite_matrix_t path_matrix; - vg_lite_identity(&path_matrix); - lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix); + if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false, true)) { + vg_lite_matrix_t path_matrix = u->global_matrix; /* move image to center */ vg_lite_translate(cx - radius_out, cy - radius_out, &matrix); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_border.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_border.c index 445ab1a5f..5860baa1f 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_border.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_border.c @@ -83,9 +83,7 @@ void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc lv_vg_lite_path_end(path); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); + vg_lite_matrix_t matrix = u->global_matrix; vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_fill.c index cae20a8fc..dbfd63df5 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_fill.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_fill.c @@ -57,22 +57,15 @@ void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * LV_PROFILER_BEGIN; - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); - - int32_t w = lv_area_get_width(coords); - int32_t h = lv_area_get_height(coords); - float r = dsc->radius; - if(dsc->radius) { - float r_short = LV_MIN(w, h) / 2.0f; - r = LV_MIN(r, r_short); - } + vg_lite_matrix_t matrix = u->global_matrix; lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_vg_lite_path_set_quality(path, dsc->radius == 0 ? VG_LITE_LOW : VG_LITE_HIGH); lv_vg_lite_path_set_bonding_box_area(path, &clip_area); - lv_vg_lite_path_append_rect(path, coords->x1, coords->y1, w, h, r); + lv_vg_lite_path_append_rect(path, + coords->x1, coords->y1, + lv_area_get_width(coords), lv_area_get_height(coords), + dsc->radius); lv_vg_lite_path_end(path); vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_img.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_img.c index 84ce9d268..86e43375e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_img.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_img.c @@ -74,7 +74,10 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * vg_lite_buffer_t src_buf; lv_image_decoder_dsc_t decoder_dsc; - if(!lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->src, no_cache)) { + + /* if not support blend normal, premultiply alpha */ + bool premultiply = !lv_vg_lite_support_blend_normal(); + if(!lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->src, no_cache, premultiply)) { LV_PROFILER_END; return; } @@ -91,13 +94,22 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * lv_memset(&color, dsc->opa, sizeof(color)); } - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); - lv_vg_lite_image_matrix(&matrix, coords->x1, coords->y1, dsc); + /* convert the blend mode to vg-lite blend mode, considering the premultiplied alpha */ + bool has_pre_mul = lv_draw_buf_has_flag(decoder_dsc.decoded, LV_IMAGE_FLAGS_PREMULTIPLIED); + vg_lite_blend_t blend = lv_vg_lite_blend_mode(dsc->blend_mode, has_pre_mul); + + /* original image matrix */ + vg_lite_matrix_t image_matrix; + vg_lite_identity(&image_matrix); + lv_vg_lite_image_matrix(&image_matrix, coords->x1, coords->y1, dsc); + + /* image drawing matrix */ + vg_lite_matrix_t matrix = u->global_matrix; + lv_vg_lite_matrix_multiply(&matrix, &image_matrix); LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf); LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); + LV_VG_LITE_ASSERT_MATRIX(&matrix); bool no_transform = lv_matrix_is_identity_or_translation((const lv_matrix_t *)&matrix); vg_lite_filter_t filter = no_transform ? VG_LITE_FILTER_POINT : VG_LITE_FILTER_BI_LINEAR; @@ -118,7 +130,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * &src_buf, &rect, &matrix, - lv_vg_lite_blend_mode(dsc->blend_mode), + blend, color, filter)); LV_PROFILER_END_TAG("vg_lite_blit_rect"); @@ -126,23 +138,22 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * else { lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); - if(dsc->clip_radius) { - int32_t width = lv_area_get_width(coords); - int32_t height = lv_area_get_height(coords); - float r_short = LV_MIN(width, height) / 2.0f; - float radius = LV_MIN(dsc->clip_radius, r_short); - - /** - * When clip_radius is enabled, the clipping edges - * are aligned with the image edges - */ + /** + * When the image is transformed or rounded, create a path around + * the image and follow the image_matrix for coordinate transformation + */ + if(!no_transform || dsc->clip_radius) { + /* apply the image transform to the path */ + lv_vg_lite_path_set_transform(path, &image_matrix); lv_vg_lite_path_append_rect( path, - coords->x1, coords->y1, - width, height, - radius); + 0, 0, + lv_area_get_width(coords), lv_area_get_height(coords), + dsc->clip_radius); + lv_vg_lite_path_set_transform(path, NULL); } else { + /* append normal rect to the path */ lv_vg_lite_path_append_rect( path, clip_area.x1, clip_area.y1, @@ -156,9 +167,8 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); LV_VG_LITE_ASSERT_PATH(vg_lite_path); - vg_lite_matrix_t path_matrix; - vg_lite_identity(&path_matrix); - lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix); + vg_lite_matrix_t path_matrix = u->global_matrix; + LV_VG_LITE_ASSERT_MATRIX(&path_matrix); LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern"); LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern( @@ -168,7 +178,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * &path_matrix, &src_buf, &matrix, - lv_vg_lite_blend_mode(dsc->blend_mode), + blend, VG_LITE_PATTERN_COLOR, 0, color, diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_label.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_label.c index 0ad4b15b0..6c4c365d8 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_label.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_label.c @@ -150,9 +150,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d lv_area_t image_area = *dsc->letter_coords; - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); + vg_lite_matrix_t matrix = u->global_matrix; vg_lite_translate(image_area.x1, image_area.y1, &matrix); vg_lite_buffer_t src_buf; @@ -198,9 +196,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); LV_VG_LITE_ASSERT_PATH(vg_lite_path); - vg_lite_matrix_t path_matrix; - vg_lite_identity(&path_matrix); - lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix); + vg_lite_matrix_t path_matrix = u->global_matrix; LV_VG_LITE_ASSERT_MATRIX(&path_matrix); LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern"); @@ -255,10 +251,7 @@ static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_ vg_lite_identity(&matrix); /* matrix for drawing, different from matrix for calculating the bonding box */ - vg_lite_matrix_t draw_matrix; - vg_lite_identity(&draw_matrix); - - lv_vg_lite_matrix_multiply(&draw_matrix, &u->global_matrix); + vg_lite_matrix_t draw_matrix = u->global_matrix; /* convert to vg-lite coordinate */ vg_lite_translate(pos.x - dsc->g->ofs_x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &draw_matrix); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_line.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_line.c index 501e8b653..e1ba695b7 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_line.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_line.c @@ -180,9 +180,7 @@ void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * lv_vg_lite_path_end(path); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); + vg_lite_matrix_t matrix = u->global_matrix; vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c index e6c0decb2..3d24b2375 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c @@ -102,28 +102,23 @@ void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_re int32_t w = lv_area_get_width(&dsc->area); int32_t h = lv_area_get_height(&dsc->area); - float r = dsc->radius; - if(dsc->radius) { - float r_short = LV_MIN(w, h) / 2.0f; - r = LV_MIN(r, r_short); - } lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_vg_lite_path_set_quality(path, VG_LITE_HIGH); lv_vg_lite_path_set_bonding_box_area(path, &draw_area); /* Use rounded rectangles and normal rectangles of the same size to nest the cropped area */ - lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, r); + lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, dsc->radius); lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, 0); lv_vg_lite_path_end(path); vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); - vg_lite_matrix_t * matrix = &u->global_matrix; + vg_lite_matrix_t matrix = u->global_matrix; LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); LV_VG_LITE_ASSERT_PATH(vg_lite_path); - LV_VG_LITE_ASSERT_MATRIX(matrix); + LV_VG_LITE_ASSERT_MATRIX(&matrix); /* Use VG_LITE_BLEND_DST_IN (Sa * D) blending mode to make the corners transparent */ LV_PROFILER_BEGIN_TAG("vg_lite_draw"); @@ -131,7 +126,7 @@ void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_re &u->target_buffer, vg_lite_path, VG_LITE_FILL_EVEN_ODD, - matrix, + &matrix, VG_LITE_BLEND_DST_IN, 0)); LV_PROFILER_END_TAG("vg_lite_draw"); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_triangle.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_triangle.c index e0258984f..63609130e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_triangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_triangle.c @@ -71,9 +71,7 @@ void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); LV_VG_LITE_ASSERT_PATH(vg_lite_path); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); + vg_lite_matrix_t matrix = u->global_matrix; LV_VG_LITE_ASSERT_MATRIX(&matrix); if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) { diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_vector.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_vector.c index a70caf804..481be5cdb 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_vector.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_vector.c @@ -217,7 +217,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec /* draw image */ vg_lite_buffer_t image_buffer; lv_image_decoder_dsc_t decoder_dsc; - if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false)) { + if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false, true)) { /* Calculate pattern matrix. Should start from path bond box, and also apply fill matrix. */ lv_matrix_t m = dsc->matrix; lv_matrix_translate(&m, min_x, min_y); @@ -251,7 +251,15 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec break; case LV_VECTOR_DRAW_STYLE_GRADIENT: { vg_lite_matrix_t grad_matrix; - lv_vg_lite_matrix(&grad_matrix, &dsc->fill_dsc.matrix); + vg_lite_identity(&grad_matrix); + +#if !LV_USE_VG_LITE_THORVG + /* Workaround inconsistent matrix behavior between device and ThorVG */ + lv_vg_lite_matrix_multiply(&grad_matrix, &matrix); +#endif + vg_lite_matrix_t fill_matrix; + lv_vg_lite_matrix(&fill_matrix, &dsc->fill_dsc.matrix); + lv_vg_lite_matrix_multiply(&grad_matrix, &fill_matrix); lv_vg_lite_draw_grad( u, diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.c index 1c530072a..9a9346b8a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.c @@ -36,8 +36,10 @@ struct lv_vg_lite_path_t { vg_lite_path_t base; + vg_lite_matrix_t matrix; size_t mem_size; uint8_t format_len; + bool has_transform; }; typedef struct { @@ -138,6 +140,7 @@ void lv_vg_lite_path_reset(lv_vg_lite_path_t * path, vg_lite_format_t data_forma path->base.quality = VG_LITE_MEDIUM; path->base.path_type = VG_LITE_DRAW_ZERO; path->format_len = lv_vg_lite_path_format_len(data_format); + path->has_transform = false; } vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path) @@ -234,6 +237,16 @@ bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path) return true; } +void lv_vg_lite_path_set_transform(lv_vg_lite_path_t * path, const vg_lite_matrix_t * matrix) +{ + LV_ASSERT_NULL(path); + if(matrix) { + path->matrix = *matrix; + } + + path->has_transform = matrix ? true : false; +} + void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t quality) { LV_ASSERT_NULL(path); @@ -267,6 +280,15 @@ static void lv_vg_lite_path_append_op(lv_vg_lite_path_t * path, uint32_t op) static void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, float y) { + if(path->has_transform) { + LV_VG_LITE_ASSERT_MATRIX(&path->matrix); + /* transform point */ + float ori_x = x; + float ori_y = y; + x = ori_x * path->matrix.m[0][0] + ori_y * path->matrix.m[0][1] + path->matrix.m[0][2]; + y = ori_x * path->matrix.m[1][0] + ori_y * path->matrix.m[1][1] + path->matrix.m[1][2]; + } + if(path->base.format == VG_LITE_FP32) { lv_vg_lite_path_append_data(path, &x, sizeof(x)); lv_vg_lite_path_append_data(path, &y, sizeof(y)); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.h index 6854b079a..b1ef3f894 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.h @@ -61,6 +61,8 @@ void lv_vg_lite_path_get_bonding_box(lv_vg_lite_path_t * path, bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path); +void lv_vg_lite_path_set_transform(lv_vg_lite_path_t * path, const vg_lite_matrix_t * matrix); + void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t quality); vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.c index e2b763692..116cbde3e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.c @@ -714,7 +714,7 @@ void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, co } bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src, - bool no_cache) + bool no_cache, bool premultiply) { LV_ASSERT_NULL(buffer); LV_ASSERT_NULL(decoder_dsc); @@ -722,7 +722,7 @@ bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_ds lv_image_decoder_args_t args; lv_memzero(&args, sizeof(lv_image_decoder_args_t)); - args.premultiply = !lv_vg_lite_support_blend_normal(); + args.premultiply = premultiply; args.stride_align = true; args.use_indexed = true; args.no_cache = no_cache; @@ -778,15 +778,11 @@ void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area) rect->height = lv_area_get_height(area); } -#if LV_USE_MATRIX - void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src) { lv_memcpy(dest, src, sizeof(lv_matrix_t)); } -#endif - uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format) { uint32_t size = 0; @@ -819,9 +815,9 @@ vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul) return (uint32_t)opa << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red; } -vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode) +vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul) { - if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { + if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { switch(blend_mode) { case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ return VG_LITE_BLEND_NORMAL_LVGL; @@ -842,7 +838,7 @@ vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode) switch(blend_mode) { case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ - if(vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { + if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { return VG_LITE_BLEND_PREMULTIPLY_SRC_OVER; } return VG_LITE_BLEND_SRC_OVER; @@ -883,11 +879,6 @@ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src) return false; } - if(buffer->stride < 1) { - LV_LOG_ERROR("buffer stride(%d) < 1", (int)buffer->stride); - return false; - } - if(!(buffer->tiled == VG_LITE_LINEAR || buffer->tiled == VG_LITE_TILED)) { LV_LOG_ERROR("buffer tiled(%d) is invalid", (int)buffer->tiled); return false; @@ -898,12 +889,6 @@ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src) return false; } - if((uint32_t)(uintptr_t)buffer->memory != buffer->address) { - LV_LOG_ERROR("buffer memory(%p) != address(%p)", - buffer->memory, (void *)(uintptr_t)buffer->address); - return false; - } - if(is_src && buffer->width != (vg_lite_int32_t)lv_vg_lite_width_align(buffer->width)) { LV_LOG_ERROR("buffer width(%d) is not aligned", (int)buffer->width); return false; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.h index 62e65620d..becbce893 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.h @@ -131,13 +131,13 @@ void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, co void lv_vg_lite_image_dec_init(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc); bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src, - bool no_cache); + bool no_cache, bool premultiply); void lv_vg_lite_image_dsc_init(struct lv_draw_vg_lite_unit_t * unit); void lv_vg_lite_image_dsc_deinit(struct lv_draw_vg_lite_unit_t * unit); -vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode); +vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul); uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format); @@ -145,12 +145,8 @@ vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul); void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area); -#if LV_USE_MATRIX - void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src); -#endif - /* Param checker */ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c index 42e6a9f70..02c9dfa7d 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c @@ -61,7 +61,7 @@ lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h) return NULL; } uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(disp)); - uint32_t buf_size = stride * w; + uint32_t buf_size = stride * h; dsc->fb1 = malloc(buf_size); if(dsc->fb1 == NULL) { lv_free(dsc); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h index 6d1844c6b..bced3e219 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h @@ -18,6 +18,10 @@ extern "C" { #if LV_USE_LIBINPUT +#if LV_LIBINPUT_XKB +#include "lv_xkb_private.h" +#endif + /********************* * DEFINES *********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.h b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.h index daaa4dc1d..3f9fd86ea 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.h @@ -18,6 +18,7 @@ extern "C" { #if defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB +#include "../../misc/lv_types.h" #include #include diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_lcd.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_lcd.c index 228c44593..af49cd44d 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_lcd.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_lcd.c @@ -216,11 +216,11 @@ static void display_release_cb(lv_event_t * e) /* clear display buffer */ if(disp->buf_1) { - lv_free(disp->buf_1); + lv_free(disp->buf_1->data); disp->buf_1 = NULL; } if(disp->buf_2) { - lv_free(disp->buf_2); + lv_free(disp->buf_2->data); disp->buf_2 = NULL; } diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.c b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.c index 8448e79d4..df8a28e4e 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.c @@ -122,7 +122,7 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res) lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * disp->ver_res, LV_SDL_RENDER_MODE); } -#else /*/*LV_USE_DRAW_SDL == 1*/ +#else /*LV_USE_DRAW_SDL == 1*/ /*It will render directly to default Texture, so the buffer is not used, so just set something*/ static lv_draw_buf_t draw_buf; static uint8_t dummy_buf; /*It won't be used as it will render to the SDL textures directly*/ @@ -166,7 +166,7 @@ lv_display_t * lv_sdl_get_disp_from_win_id(uint32_t win_id) while(disp) { lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); - if(SDL_GetWindowID(dsc->window) == win_id) { + if(dsc != NULL && SDL_GetWindowID(dsc->window) == win_id) { return disp; } disp = lv_display_get_next(disp); diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c index 5d0810747..3a4a5721a 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c @@ -1203,11 +1203,6 @@ static void indev_proc_press(lv_indev_t * indev) lv_obj_send_event(last_obj, LV_EVENT_PRESS_LOST, indev_act); if(indev_reset_check(indev)) return; - - /*Do nothing until release and a new press*/ - lv_indev_reset(indev, NULL); - lv_indev_wait_release(indev); - return; } indev->pointer.act_obj = indev_obj_act; /*Save the pressed object*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c b/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c index 8e97ab503..ffe9ec1f5 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c @@ -113,9 +113,21 @@ static gd_GIF * gif_open(gd_GIF * gif_base) /* Aspect Ratio */ f_gif_read(gif_base, &aspect, 1); /* Create gd_GIF Structure. */ + if(0 == width || 0 == height){ + LV_LOG_WARN("Zero size image"); + goto fail; + } #if LV_GIF_CACHE_DECODE_DATA + if(0 == (INT_MAX - sizeof(gd_GIF) - LZW_CACHE_SIZE) / width / height / 5){ + LV_LOG_WARN("Image dimensions are too large"); + goto fail; + } gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height + LZW_CACHE_SIZE); #else + if(0 == (INT_MAX - sizeof(gd_GIF)) / width / height / 5){ + LV_LOG_WARN("Image dimensions are too large"); + goto fail; + } gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height); #endif if(!gif) goto fail; @@ -318,6 +330,8 @@ get_key(gd_GIF *gif, int key_size, uint8_t *sub_len, uint8_t *shift, uint8_t *by } #if LV_GIF_CACHE_DECODE_DATA +/* Decompress image pixels. + * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */ static int read_image_data(gd_GIF *gif, int interlace) { @@ -375,6 +389,10 @@ read_image_data(gd_GIF *gif, int interlace) while (frm_off < frm_size) { /* copy data to frame buffer */ while (sp > p_stack) { + if(frm_off >= frm_size){ + LV_LOG_WARN("LZW table token overflows the frame buffer"); + return -1; + } *ptr++ = *(--sp); frm_off += 1; /* read one line */ @@ -526,7 +544,7 @@ interlaced_line_index(int h, int y) } /* Decompress image pixels. - * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table). */ + * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */ static int read_image_data(gd_GIF * gif, int interlace) { @@ -578,6 +596,10 @@ read_image_data(gd_GIF * gif, int interlace) if(ret == 1) key_size++; entry = table->entries[key]; str_len = entry.length; + if(frm_off + str_len >= frm_size){ + LV_LOG_WARN("LZW table token overflows the frame buffer"); + return -1; + } for(i = 0; i < str_len; i++) { p = frm_off + entry.length - 1; x = p % gif->fw; @@ -603,7 +625,7 @@ read_image_data(gd_GIF * gif, int interlace) #endif /* Read image. - * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table). */ + * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */ static int read_image(gd_GIF * gif) { @@ -615,6 +637,10 @@ read_image(gd_GIF * gif) gif->fy = read_num(gif); gif->fw = read_num(gif); gif->fh = read_num(gif); + if(gif->fx + (uint32_t)gif->fw > gif->width || gif->fy + (uint32_t)gif->fh > gif->height){ + LV_LOG_WARN("Frame coordinates out of image bounds"); + return -1; + } f_gif_read(gif, &fisrz, 1); interlace = fisrz & 0x40; /* Ignore Sort Flag. */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c index ca48f13fd..920f77689 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c @@ -137,6 +137,36 @@ void lv_gif_resume(lv_obj_t * obj) lv_timer_resume(gifobj->timer); } +bool lv_gif_is_loaded(lv_obj_t * obj) +{ + lv_gif_t * gifobj = (lv_gif_t *) obj; + + return (gifobj->gif != NULL); +} + +int32_t lv_gif_get_loop_count(lv_obj_t * obj) +{ + lv_gif_t * gifobj = (lv_gif_t *) obj; + + if(gifobj->gif == NULL) { + return -1; + } + + return gifobj->gif->loop_count; +} + +void lv_gif_set_loop_count(lv_obj_t * obj, int32_t count) +{ + lv_gif_t * gifobj = (lv_gif_t *) obj; + + if(gifobj->gif == NULL) { + LV_LOG_WARN("Gif resource not loaded correctly"); + return; + } + + gifobj->gif->loop_count = count; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h index fc6323fa6..cf1bee479 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h @@ -72,6 +72,25 @@ void lv_gif_pause(lv_obj_t * obj); */ void lv_gif_resume(lv_obj_t * obj); +/** + * Checks if the GIF was loaded correctly. + * @param obj pointer to a gif obj + */ +bool lv_gif_is_loaded(lv_obj_t * obj); + +/** + * Get the loop count for the GIF. + * @param obj pointer to a gif obj + */ +int32_t lv_gif_get_loop_count(lv_obj_t * obj); + +/** + * Set the loop count for the GIF. + * @param obj pointer to a gif obj + * @param count the loop count to set + */ +void lv_gif_set_loop_count(lv_obj_t * obj, int32_t count); + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h b/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h index 5cebb73f1..0a66d949e 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h @@ -266,6 +266,24 @@ #endif #endif #endif +#if LV_USE_OS == LV_OS_FREERTOS + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ + #ifndef LV_USE_FREERTOS_TASK_NOTIFY + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_FREERTOS_TASK_NOTIFY + #define LV_USE_FREERTOS_TASK_NOTIFY CONFIG_LV_USE_FREERTOS_TASK_NOTIFY + #else + #define LV_USE_FREERTOS_TASK_NOTIFY 0 + #endif + #else + #define LV_USE_FREERTOS_TASK_NOTIFY 1 + #endif + #endif +#endif /*======================== * RENDERING CONFIGURATION @@ -610,16 +628,38 @@ #endif /* Use NXP's PXP on iMX RTxxx platforms. */ -#ifndef LV_USE_DRAW_PXP - #ifdef CONFIG_LV_USE_DRAW_PXP - #define LV_USE_DRAW_PXP CONFIG_LV_USE_DRAW_PXP +#ifndef LV_USE_PXP + #ifdef CONFIG_LV_USE_PXP + #define LV_USE_PXP CONFIG_LV_USE_PXP #else - #define LV_USE_DRAW_PXP 0 + #define LV_USE_PXP 0 #endif #endif -#if LV_USE_DRAW_PXP - #if LV_USE_OS +#if LV_USE_PXP + /* Use PXP for drawing.*/ + #ifndef LV_USE_DRAW_PXP + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_DRAW_PXP + #define LV_USE_DRAW_PXP CONFIG_LV_USE_DRAW_PXP + #else + #define LV_USE_DRAW_PXP 0 + #endif + #else + #define LV_USE_DRAW_PXP 1 + #endif + #endif + + /* Use PXP to rotate display.*/ + #ifndef LV_USE_ROTATE_PXP + #ifdef CONFIG_LV_USE_ROTATE_PXP + #define LV_USE_ROTATE_PXP CONFIG_LV_USE_ROTATE_PXP + #else + #define LV_USE_ROTATE_PXP 0 + #endif + #endif + + #if LV_USE_DRAW_PXP && LV_USE_OS /* Use additional draw thread for PXP processing.*/ #ifndef LV_USE_PXP_DRAW_THREAD #ifdef LV_KCONFIG_PRESENT diff --git a/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h b/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h index a36eaf775..7796e0fb9 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h @@ -18,6 +18,16 @@ extern "C" { # ifdef __NuttX__ # include +/* + * Make sure version number in Kconfig file is correctly set. + * Mismatch can happen when user manually copy lvgl/Kconfig file to their project, like what NuttX does. + */ +# include "../lv_version.h" + +# if CONFIG_LVGL_VERSION_MAJOR != LVGL_VERSION_MAJOR || CONFIG_LVGL_VERSION_MINOR != LVGL_VERSION_MINOR \ + || CONFIG_LVGL_VERSION_PATCH != LVGL_VERSION_PATCH +# warning "Version mismatch between Kconfig and lvgl/lv_version.h" +# endif # elif defined(__RTTHREAD__) # define LV_CONF_INCLUDE_SIMPLE # include diff --git a/lib/libesp32_lvgl/lvgl/src/lv_init.c b/lib/libesp32_lvgl/lvgl/src/lv_init.c index 26897a7bc..a019d6e57 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_init.c +++ b/lib/libesp32_lvgl/lvgl/src/lv_init.c @@ -43,8 +43,10 @@ #if LV_USE_DRAW_VGLITE #include "draw/nxp/vglite/lv_draw_vglite.h" #endif -#if LV_USE_DRAW_PXP - #include "draw/nxp/pxp/lv_draw_pxp.h" +#if LV_USE_PXP + #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP + #include "draw/nxp/pxp/lv_draw_pxp.h" + #endif #endif #if LV_USE_DRAW_DAVE2D #include "draw/renesas/dave2d/lv_draw_dave2d.h" @@ -198,9 +200,11 @@ void lv_init(void) lv_draw_vglite_init(); #endif -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP lv_draw_pxp_init(); #endif +#endif #if LV_USE_DRAW_DAVE2D lv_draw_dave2d_init(); @@ -385,9 +389,11 @@ void lv_deinit(void) lv_obj_style_deinit(); -#if LV_USE_DRAW_PXP +#if LV_USE_PXP +#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP lv_draw_pxp_deinit(); #endif +#endif #if LV_USE_DRAW_VGLITE lv_draw_vglite_deinit(); diff --git a/lib/libesp32_lvgl/lvgl/src/lvgl_private.h b/lib/libesp32_lvgl/lvgl/src/lvgl_private.h index cda92217b..8ab64e973 100644 --- a/lib/libesp32_lvgl/lvgl/src/lvgl_private.h +++ b/lib/libesp32_lvgl/lvgl/src/lvgl_private.h @@ -70,7 +70,6 @@ extern "C" { #include "widgets/buttonmatrix/lv_buttonmatrix_private.h" #include "widgets/slider/lv_slider_private.h" #include "widgets/switch/lv_switch_private.h" -#include "widgets/calendar/lv_calendar_chinese_private.h" #include "widgets/calendar/lv_calendar_private.h" #include "widgets/imagebutton/lv_imagebutton_private.h" #include "widgets/bar/lv_bar_private.h" diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c index 0e57f2435..8fc986764 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c @@ -138,7 +138,7 @@ uint32_t lv_anim_get_playtime(const lv_anim_t * a) if(repeat_cnt < 1) repeat_cnt = 1; uint32_t playtime = a->repeat_delay + a->duration + a->playback_delay + a->playback_duration; - playtime = playtime * a->repeat_cnt; + playtime = playtime * repeat_cnt; return playtime; } diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi_private.h index d197e4ac4..0b684daec 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi_private.h @@ -15,6 +15,7 @@ extern "C" { *********************/ #include "lv_bidi.h" +#if LV_USE_BIDI /********************* * DEFINES @@ -91,6 +92,8 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len * MACROS **********************/ +#endif /*LV_USE_BIDI*/ + #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c index d56e355fe..d62f280b1 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c @@ -87,6 +87,7 @@ bool lv_color_format_has_alpha(lv_color_format_t cf) case LV_COLOR_FORMAT_I4: case LV_COLOR_FORMAT_I8: case LV_COLOR_FORMAT_RGB565A8: + case LV_COLOR_FORMAT_ARGB8565: case LV_COLOR_FORMAT_ARGB8888: case LV_COLOR_FORMAT_AL88: return true; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h index f8ffa1a0e..c6f938b7d 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h @@ -91,6 +91,12 @@ typedef struct { lv_fs_file_cache_t * cache; } lv_fs_file_t; + +typedef struct { + void * dir_d; + lv_fs_drv_t * drv; +} lv_fs_dir_t; + /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h index e8789e6c0..f8bb4bbd3 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h @@ -38,12 +38,6 @@ struct lv_fs_path_ex_t { uint32_t size; }; -struct lv_fs_dir_t { - void * dir_d; - lv_fs_drv_t * drv; -}; - - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h index 4e02c1366..b362e7ad0 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h @@ -139,8 +139,6 @@ typedef struct lv_fs_file_cache_t lv_fs_file_cache_t; typedef struct lv_fs_path_ex_t lv_fs_path_ex_t; -typedef struct lv_fs_dir_t lv_fs_dir_t; - typedef struct lv_image_decoder_args_t lv_image_decoder_args_t; typedef struct lv_image_cache_data_t lv_image_cache_data_t; @@ -187,8 +185,6 @@ typedef struct lv_buttonmatrix_t lv_buttonmatrix_t; typedef struct lv_calendar_t lv_calendar_t; -typedef struct lv_calendar_chinese_t lv_calendar_chinese_t; - typedef struct lv_canvas_t lv_canvas_t; typedef struct lv_chart_series_t lv_chart_series_t; diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c index 1c81a8e05..f65a299aa 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c @@ -15,11 +15,7 @@ #include "lv_os.h" #if LV_USE_OS == LV_OS_FREERTOS -#if (ESP_PLATFORM) - #include "freertos/atomic.h" -#else - #include "atomic.h" -#endif +#include "atomic.h" #include "../tick/lv_tick.h" #include "../misc/lv_log.h" @@ -54,7 +50,9 @@ static void prvCondInit(lv_thread_sync_t * pxCond); static void prvCheckCondInit(lv_thread_sync_t * pxCond); -#if !USE_FREERTOS_TASK_NOTIFY +static void prvCheckCondInitIsr(lv_thread_sync_t * pxCond); + +#if !LV_USE_FREERTOS_TASK_NOTIFY static void prvTestAndDecrement(lv_thread_sync_t * pxCond, uint32_t ulLocalWaitingThreads); #endif @@ -74,9 +72,13 @@ static void prvTestAndDecrement(lv_thread_sync_t * pxCond, #if (ESP_PLATFORM) #define _enter_critical() taskENTER_CRITICAL(&critSectionMux); #define _exit_critical() taskEXIT_CRITICAL(&critSectionMux); + #define _enter_critical_isr() taskENTER_CRITICAL_FROM_ISR(); + #define _exit_critical_isr(x) taskEXIT_CRITICAL_FROM_ISR(x); #else #define _enter_critical() taskENTER_CRITICAL(); #define _exit_critical() taskEXIT_CRITICAL(); + #define _enter_critical_isr() taskENTER_CRITICAL_FROM_ISR(); + #define _exit_critical_isr(x) taskEXIT_CRITICAL_FROM_ISR(x); #endif /********************** @@ -195,20 +197,20 @@ lv_result_t lv_thread_sync_wait(lv_thread_sync_t * pxCond) /* If the cond is uninitialized, perform initialization. */ prvCheckCondInit(pxCond); -#if USE_FREERTOS_TASK_NOTIFY - TaskHandle_t current_task_handle = xTaskGetCurrentTaskHandle(); +#if LV_USE_FREERTOS_TASK_NOTIFY + TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle(); _enter_critical(); - BaseType_t signal_sent = pxCond->xSyncSignal; + BaseType_t xSyncSygnal = pxCond->xSyncSignal; pxCond->xSyncSignal = pdFALSE; - if(signal_sent == pdFALSE) { + if(xSyncSygnal == pdFALSE) { /* The signal hasn't been sent yet. Tell the sender to notify this task */ - pxCond->xTaskToNotify = current_task_handle; + pxCond->xTaskToNotify = xCurrentTaskHandle; } /* If we have a signal from the other task, we should not ask to be notified */ _exit_critical(); - if(signal_sent == pdFALSE) { + if(xSyncSygnal == pdFALSE) { /* Wait for other task to notify this task. */ ulTaskNotifyTake(pdTRUE, portMAX_DELAY); } @@ -275,20 +277,20 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * pxCond) /* If the cond is uninitialized, perform initialization. */ prvCheckCondInit(pxCond); -#if USE_FREERTOS_TASK_NOTIFY +#if LV_USE_FREERTOS_TASK_NOTIFY _enter_critical(); - TaskHandle_t task_to_notify = pxCond->xTaskToNotify; + TaskHandle_t xTaskToNotify = pxCond->xTaskToNotify; pxCond->xTaskToNotify = NULL; - if(task_to_notify == NULL) { + if(xTaskToNotify == NULL) { /* No task waiting to be notified. Send this signal for later */ pxCond->xSyncSignal = pdTRUE; } /* If a task is already waiting, there is no need to set the sync signal */ _exit_critical(); - if(task_to_notify != NULL) { + if(xTaskToNotify != NULL) { /* There is a task waiting. Send a notification to it */ - xTaskNotifyGive(task_to_notify); + xTaskNotifyGive(xTaskToNotify); } /* If there was no task waiting to be notified, we sent a signal for it to see later. */ #else @@ -329,13 +331,13 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * pxCond) lv_result_t lv_thread_sync_delete(lv_thread_sync_t * pxCond) { -#if !USE_FREERTOS_TASK_NOTIFY +#if !LV_USE_FREERTOS_TASK_NOTIFY /* Cleanup all resources used by the cond. */ vSemaphoreDelete(pxCond->xCondWaitSemaphore); vSemaphoreDelete(pxCond->xSyncMutex); pxCond->ulWaitingThreads = 0; - pxCond->xSyncSignal = pdFALSE; #endif + pxCond->xSyncSignal = pdFALSE; pxCond->xIsInitialized = pdFALSE; return LV_RESULT_OK; @@ -346,28 +348,28 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * pxCond) BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* If the cond is uninitialized, perform initialization. */ - prvCheckCondInit(pxCond); + prvCheckCondInitIsr(pxCond); -#if USE_FREERTOS_TASK_NOTIFY - _enter_critical(); - TaskHandle_t task_to_notify = pxCond->xTaskToNotify; +#if LV_USE_FREERTOS_TASK_NOTIFY + uint32_t mask = _enter_critical_isr(); + TaskHandle_t xTaskToNotify = pxCond->xTaskToNotify; pxCond->xTaskToNotify = NULL; - if(task_to_notify == NULL) { + if(xTaskToNotify == NULL) { /* No task waiting to be notified. Send this signal for later */ pxCond->xSyncSignal = pdTRUE; } /* If a task is already waiting, there is no need to set the sync signal */ - _exit_critical(); + _exit_critical_isr(mask); - if(task_to_notify != NULL) { + if(xTaskToNotify != NULL) { /* There is a task waiting. Send a notification to it */ - vTaskNotifyGiveFromISR(task_to_notify, &xHigherPriorityTaskWoken); + vTaskNotifyGiveFromISR(xTaskToNotify, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /* If there was no task waiting to be notified, we sent a signal for it to see later. */ #else /* Enter critical section to prevent preemption. */ - _enter_critical(); + uint32_t mask = _enter_critical_isr(); pxCond->xSyncSignal = pdTRUE; BaseType_t xAnyHigherPriorityTaskWoken = pdFALSE; @@ -378,7 +380,7 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * pxCond) xHigherPriorityTaskWoken |= xAnyHigherPriorityTaskWoken; } - _exit_critical(); + _exit_critical_isr(mask); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); #endif @@ -470,7 +472,7 @@ static void prvCondInit(lv_thread_sync_t * pxCond) pxCond->xIsInitialized = pdTRUE; pxCond->xSyncSignal = pdFALSE; -#if USE_FREERTOS_TASK_NOTIFY +#if LV_USE_FREERTOS_TASK_NOTIFY pxCond->xTaskToNotify = NULL; #else pxCond->xCondWaitSemaphore = xSemaphoreCreateCounting(ulMAX_COUNT, 0U); @@ -516,7 +518,27 @@ static void prvCheckCondInit(lv_thread_sync_t * pxCond) } } -#if !USE_FREERTOS_TASK_NOTIFY +static void prvCheckCondInitIsr(lv_thread_sync_t * pxCond) +{ + /* Check if the condition variable needs to be initialized. */ + if(pxCond->xIsInitialized == pdFALSE) { + /* Cond initialization must be in a critical section to prevent two + * threads from initializing it at the same time. */ + uint32_t mask = _enter_critical_isr(); + + /* Check again that the condition is still uninitialized, i.e. it wasn't + * initialized while this function was waiting to enter the critical + * section. */ + if(pxCond->xIsInitialized == pdFALSE) { + prvCondInit(pxCond); + } + + /* Exit the critical section. */ + _exit_critical_isr(mask); + } +} + +#if !LV_USE_FREERTOS_TASK_NOTIFY static void prvTestAndDecrement(lv_thread_sync_t * pxCond, uint32_t ulLocalWaitingThreads) { diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h index 2e2384d37..67a5a1e7f 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h @@ -37,14 +37,6 @@ extern "C" { * DEFINES *********************/ -/* - * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM - * than unblocking a task using an intermediary object such as a binary semaphore. - * - * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. - */ -#define USE_FREERTOS_TASK_NOTIFY 1 - /********************** * TYPEDEFS **********************/ @@ -64,7 +56,7 @@ typedef struct { BaseType_t xIsInitialized; /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */ BaseType_t xSyncSignal; /**< Set to pdTRUE if the thread is signaled, pdFALSE otherwise. */ -#if USE_FREERTOS_TASK_NOTIFY +#if LV_USE_FREERTOS_TASK_NOTIFY TaskHandle_t xTaskToNotify; /**< The task waiting to be signalled. NULL if nothing is waiting. */ #else SemaphoreHandle_t xCondWaitSemaphore; /**< Threads block on this semaphore in lv_thread_sync_wait. */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.c b/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.c index 08f43a143..8382269b7 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.c +++ b/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.c @@ -707,7 +707,8 @@ static void lv_ime_pinyin_kb_event(lv_event_t * e) } else if((pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) && ((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' && txt[0] <= 'Z'))) { - lv_strcat(pinyin_ime->input_char, txt); + uint16_t len = lv_strlen(pinyin_ime->input_char); + lv_snprintf(pinyin_ime->input_char + len, sizeof(pinyin_ime->input_char) - len, "%s", txt); pinyin_input_proc(obj); pinyin_ime->ta_count++; } @@ -877,8 +878,8 @@ static void init_pinyin_dict(lv_obj_t * obj, const lv_pinyin_dict_t * dict) } else { headletter = dict[i].py[0]; + pinyin_ime->py_num[letter_calc] = offset_count; letter_calc = headletter - 'a'; - pinyin_ime->py_num[letter_calc - 1] = offset_count; offset_sum += offset_count; pinyin_ime->py_pos[letter_calc] = offset_sum; diff --git a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c index 1814dddf9..803ce8c5e 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c +++ b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c @@ -277,11 +277,10 @@ static void perf_update_timer_cb(lv_timer_t * t) static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject) { - lv_obj_t * label = lv_observer_get_target(observer); const lv_sysmon_perf_info_t * perf = lv_subject_get_pointer(subject); #if LV_USE_PERF_MONITOR_LOG_MODE - LV_UNUSED(label); + LV_UNUSED(observer); LV_LOG("sysmon: " "%" LV_PRIu32 " FPS (refr_cnt: %" LV_PRIu32 " | redraw_cnt: %" LV_PRIu32"), " "refr %" LV_PRIu32 "ms (render %" LV_PRIu32 "ms | flush %" LV_PRIu32 "ms), " @@ -290,6 +289,7 @@ static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject) perf->calculated.refr_avg_time, perf->calculated.render_avg_time, perf->calculated.flush_avg_time, perf->calculated.cpu); #else + lv_obj_t * label = lv_observer_get_target(observer); lv_label_set_text_fmt( label, "%" LV_PRIu32" FPS, %" LV_PRIu32 "%% CPU\n" diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c index 11ec7ca1c..548c48c8c 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c @@ -134,6 +134,13 @@ uint32_t lv_animimg_get_repeat_count(lv_obj_t * obj) return lv_anim_get_repeat_count(&animimg->anim); } +lv_anim_t * lv_animimg_get_anim(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_animimg_t * animimg = (lv_animimg_t *)obj; + return &animimg->anim; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h index c7b3b0a8b..a2f1926c1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h @@ -14,6 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../image/lv_image.h" +#include "../../misc/lv_types.h" #if LV_USE_ANIMIMG != 0 @@ -112,6 +113,13 @@ uint32_t lv_animimg_get_duration(lv_obj_t * img); */ uint32_t lv_animimg_get_repeat_count(lv_obj_t * img); +/** + * Get the image animation underlying animation. + * @param img pointer to an animation image object + * @return the animation reference + */ +lv_anim_t * lv_animimg_get_anim(lv_obj_t * img); + #endif /*LV_USE_ANIMIMG*/ #ifdef __cplusplus diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c index 7e4315c29..6aa14840d 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c @@ -199,6 +199,9 @@ void lv_arc_set_rotation(lv_obj_t * obj, int32_t rotation) LV_ASSERT_OBJ(obj, MY_CLASS); lv_arc_t * arc = (lv_arc_t *)obj; + /* ensure the angle is in the range [0, 360) */ + while(rotation < 0) rotation += 360; + while(rotation >= 360) rotation -= 360; arc->rotation = rotation; lv_obj_invalidate(obj); @@ -506,8 +509,9 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e) angle -= arc->rotation; angle -= arc->bg_angle_start; /*Make the angle relative to the start angle*/ - /* If we click near the bg_angle_start the angle will be close to 360° instead of a small angle */ - if(angle < 0) angle += 360; + /* ensure the angle is in the range [0, 360) */ + while(angle < 0) angle += 360; + while(angle >= 360) angle -= 360; const uint32_t circumference = (uint32_t)((2U * r * 314U) / 100U); /* Equivalent to: 2r * 3.14, avoiding floats */ const lv_value_precise_t tolerance_deg = (360 * lv_dpx(50U)) / circumference; @@ -655,6 +659,25 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e) return; } + /*Calculate the angle of the pressed point*/ + lv_value_precise_t angle = lv_atan2(info->point->y - p.y, info->point->x - p.x); + angle -= arc->rotation; + angle -= arc->bg_angle_start; /*Make the angle relative to the start angle*/ + + /* ensure the angle is in the range [0, 360) */ + while(angle < 0) angle += 360; + while(angle >= 360) angle -= 360; + + const uint32_t circumference = (uint32_t)((2U * r * 314U) / 100U); /* Equivalent to: 2r * 3.14, avoiding floats */ + const lv_value_precise_t tolerance_deg = (360 * lv_dpx(50U)) / circumference; + + /* Check if the angle is outside the drawn background arc */ + const bool is_angle_within_bg_bounds = lv_arc_angle_within_bg_bounds(obj, angle, tolerance_deg); + if(!is_angle_within_bg_bounds) { + info->res = false; + return; + } + /*Valid if no clicked outside*/ lv_area_increase(&a, w + ext_click_area * 2, w + ext_click_area * 2); info->res = lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE); @@ -941,7 +964,10 @@ static bool lv_arc_angle_within_bg_bounds(lv_obj_t * obj, const lv_value_precise lv_arc_t * arc = (lv_arc_t *)obj; lv_value_precise_t bounds_angle = arc->bg_angle_end - arc->bg_angle_start; - if(bounds_angle < 0) bounds_angle += 360; + + /* ensure the angle is in the range [0, 360) */ + while(bounds_angle < 0) bounds_angle += 360; + while(bounds_angle >= 360) bounds_angle -= 360; /* Angle is in the bounds */ if(angle <= bounds_angle) { diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h index 891d14a34..1a8dd4bb1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h @@ -44,8 +44,8 @@ struct lv_bar_t { bool val_reversed; /**< Whether value been reversed */ lv_bar_anim_t cur_value_anim; lv_bar_anim_t start_value_anim; - lv_bar_mode_t mode : 2; /**< Type of bar*/ - lv_bar_orientation_t orientation : 2; /**< Orientation of bar*/ + lv_bar_mode_t mode : 3; /**< Type of bar*/ + lv_bar_orientation_t orientation : 3; /**< Orientation of bar*/ }; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c index b05602de4..e20ac2ebe 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c @@ -51,7 +51,7 @@ static bool button_is_popover(lv_buttonmatrix_ctrl_t ctrl_bits); static bool button_is_checkable(lv_buttonmatrix_ctrl_t ctrl_bits); static bool button_get_checked(lv_buttonmatrix_ctrl_t ctrl_bits); static uint32_t get_button_from_point(lv_obj_t * obj, lv_point_t * p); -static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char ** map); +static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char * const * map); static void invalidate_button_area(const lv_obj_t * obj, uint32_t btn_idx); static void make_one_button_checked(lv_obj_t * obj, uint32_t btn_idx); static bool has_popovers_in_top_row(lv_obj_t * obj); @@ -60,7 +60,7 @@ static bool has_popovers_in_top_row(lv_obj_t * obj); * STATIC VARIABLES **********************/ #if LV_WIDGETS_HAS_DEFAULT_VALUE -static const char * lv_buttonmatrix_def_map[] = {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}; +static const char * const lv_buttonmatrix_def_map[] = {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}; #endif const lv_obj_class_t lv_buttonmatrix_class = { @@ -96,7 +96,7 @@ lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent) * Setter functions *====================*/ -void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[]) +void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[]) { LV_ASSERT_OBJ(obj, MY_CLASS); if(map == NULL) return; @@ -125,7 +125,7 @@ void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[]) *(A button can be 1,2,3... unit wide)*/ uint32_t txt_tot_i = 0; /*Act. index in the str map*/ uint32_t btn_tot_i = 0; /*Act. index of button areas*/ - const char ** map_row = map; + const char * const * map_row = map; /*Count the units and the buttons in a line*/ uint32_t row; @@ -295,7 +295,7 @@ void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en) * Getter functions *====================*/ -const char ** lv_buttonmatrix_get_map(const lv_obj_t * obj) +const char * const * lv_buttonmatrix_get_map(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -813,7 +813,7 @@ static void draw_main(lv_event_t * e) * @param obj pointer to button matrix object * @param map_p pointer to a string array */ -static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char ** map) +static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char * const * map) { lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; btnm->row_cnt = 1; @@ -1029,7 +1029,7 @@ static bool has_popovers_in_top_row(lv_obj_t * obj) return false; } - const char ** map_row = btnm->map_p; + const char * const * map_row = btnm->map_p; uint32_t btn_cnt = 0; while(map_row[btn_cnt] && lv_strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') { diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h index c095eec35..c2726627c 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h @@ -73,7 +73,7 @@ lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent); * @param obj pointer to a button matrix object * @param map pointer a string array. The last string has to be: "". Use "\n" to make a line break. */ -void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[]); +void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[]); /** * Set the button control map (hidden, disabled etc.) for a button matrix. @@ -155,7 +155,7 @@ void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en); * @param obj pointer to a button matrix object * @return the current map */ -const char ** lv_buttonmatrix_get_map(const lv_obj_t * obj); +const char * const * lv_buttonmatrix_get_map(const lv_obj_t * obj); /** * Get the index of the lastly "activated" button by the user (pressed, released, focused etc) diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h index 6893b0e1e..cab042db9 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h @@ -30,7 +30,7 @@ extern "C" { /** Data of button matrix */ struct lv_buttonmatrix_t { lv_obj_t obj; - const char ** map_p; /**< Pointer to the current map */ + const char * const * map_p; /**< Pointer to the current map */ lv_area_t * button_areas; /**< Array of areas of buttons */ lv_buttonmatrix_ctrl_t * ctrl_bits; /**< Array of control bytes */ uint32_t btn_cnt; /**< Number of button in 'map_p'(Handled by the library) */ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c index 81c844bf1..ee24133ad 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c @@ -6,7 +6,6 @@ /********************* * INCLUDES *********************/ -#include "lv_calendar_chinese_private.h" #include "lv_calendar_private.h" #if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE @@ -124,7 +123,7 @@ const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian) { uint16_t i, len; lv_calendar_chinese_t chinese_calendar; - chinese_calendar = lv_calendar_gregorian_to_chinese(gregorian); + lv_calendar_gregorian_to_chinese(gregorian, &chinese_calendar); if(gregorian->year > 2099 || gregorian->year < 1901) return NULL; @@ -170,11 +169,11 @@ const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian) return (char *)chinese_calendar_day_name[chinese_calendar.today.day - 1]; } -lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian) +void lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian_time, lv_calendar_chinese_t * chinese_time) { - uint16_t year = gregorian->year; - uint8_t month = gregorian->month; - uint8_t day = gregorian->day; + uint16_t year = gregorian_time->year; + uint8_t month = gregorian_time->month; + uint8_t day = gregorian_time->day; /*Record the number of days between the Spring Festival and the New Year's Day of that year.*/ @@ -191,14 +190,13 @@ lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * greg uint8_t index; bool leep_month; - lv_calendar_chinese_t chinese_calendar; if(year < 1901 || year > 2099) { - chinese_calendar.leep_month = 0; - chinese_calendar.today.year = 2000; - chinese_calendar.today.month = 1; - chinese_calendar.today.day = 1; - return chinese_calendar; + chinese_time->leep_month = 0; + chinese_time->today.year = 2000; + chinese_time->today.month = 1; + chinese_time->today.day = 1; + return; } if(((calendar_chinese_table[year - 1901] & 0x0060) >> 5) == 1) @@ -274,11 +272,10 @@ lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * greg day = days_per_month - by_spring + 1; } - chinese_calendar.today.day = day; - chinese_calendar.today.month = month; - chinese_calendar.today.year = year; - chinese_calendar.leep_month = leep_month; - return chinese_calendar; + chinese_time->today.day = day; + chinese_time->today.month = month; + chinese_time->today.year = year; + chinese_time->leep_month = leep_month; } /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.h b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.h index 8d5b174ab..fb7a1bc0e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.h @@ -21,6 +21,15 @@ extern "C" { * DEFINES *********************/ +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_calendar_date_t today; + bool leep_month; +} lv_calendar_chinese_t; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -41,10 +50,10 @@ const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian); /** * Get the chinese time of the gregorian time (reference: https://www.cnblogs.com/liyang31tg/p/4123171.html) - * @param gregorian need to convert to chinese time in gregorian time - * @return return the chinese time of the gregorian time + * @param gregorian_time need to convert to chinese time in gregorian time + * @param chinese_time the chinese time convert from gregorian time */ -lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian); +void lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian_time, lv_calendar_chinese_t * chinese_time); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c index 1b34b44fc..517479cdb 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c @@ -862,7 +862,6 @@ static void draw_main(lv_event_t * e) int32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN); int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width; int32_t right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width; - int32_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + border_width; lv_draw_label_dsc_t symbol_dsc; lv_draw_label_dsc_init(&symbol_dsc); @@ -906,24 +905,22 @@ static void draw_main(lv_event_t * e) } lv_area_t symbol_area; + symbol_area.y1 = obj->coords.y1; + symbol_area.y2 = symbol_area.y1 + symbol_h - 1; + symbol_area.x1 = obj->coords.x1; + symbol_area.x2 = symbol_area.x1 + symbol_w - 1; if(symbol_to_left) { - symbol_area.x1 = obj->coords.x1 + left; - symbol_area.x2 = symbol_area.x1 + symbol_w - 1; + lv_area_align(&obj->coords, &symbol_area, LV_ALIGN_LEFT_MID, left, 0); } else { - symbol_area.x1 = obj->coords.x2 - right - symbol_w; - symbol_area.x2 = symbol_area.x1 + symbol_w - 1; + lv_area_align(&obj->coords, &symbol_area, LV_ALIGN_RIGHT_MID, -right, 0); } if(symbol_type == LV_IMAGE_SRC_SYMBOL) { - symbol_area.y1 = obj->coords.y1 + top; - symbol_area.y2 = symbol_area.y1 + symbol_h - 1; symbol_dsc.text = dropdown->symbol; lv_draw_label(layer, &symbol_dsc, &symbol_area); } else { - symbol_area.y1 = obj->coords.y1 + (lv_obj_get_height(obj) - symbol_h) / 2; - symbol_area.y2 = symbol_area.y1 + symbol_h - 1; lv_draw_image_dsc_t img_dsc; lv_draw_image_dsc_init(&img_dsc); lv_obj_init_draw_image_dsc(obj, LV_PART_INDICATOR, &img_dsc); @@ -943,22 +940,21 @@ static void draw_main(lv_event_t * e) label_dsc.flag); lv_area_t txt_area; - txt_area.y1 = obj->coords.y1 + top; - txt_area.y2 = txt_area.y1 + size.y; + txt_area.x1 = obj->coords.x1; + txt_area.x2 = txt_area.x1 + size.x - 1; + txt_area.y1 = obj->coords.y1; + txt_area.y2 = txt_area.y1 + size.y - 1; /*Center align the text if no symbol*/ if(dropdown->symbol == NULL) { - txt_area.x1 = obj->coords.x1 + (lv_obj_get_width(obj) - size.x) / 2; - txt_area.x2 = txt_area.x1 + size.x; + lv_area_align(&obj->coords, &txt_area, LV_ALIGN_CENTER, 0, 0); } else { /*Text to the right*/ if(symbol_to_left) { - txt_area.x1 = obj->coords.x2 - right - size.x; - txt_area.x2 = txt_area.x1 + size.x; + lv_area_align(&obj->coords, &txt_area, LV_ALIGN_RIGHT_MID, -right, 0); } else { - txt_area.x1 = obj->coords.x1 + left; - txt_area.x2 = txt_area.x1 + size.x; + lv_area_align(&obj->coords, &txt_area, LV_ALIGN_LEFT_MID, left, 0); } } diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c index 147429436..5fdcc12d5 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c @@ -435,6 +435,11 @@ void lv_image_set_inner_align(lv_obj_t * obj, lv_image_align_t align) lv_image_t * img = (lv_image_t *)obj; if(align == img->align) return; + /*If we're removing STRETCH, reset the scale*/ + if(img->align == LV_IMAGE_ALIGN_STRETCH) { + lv_image_set_scale(obj, LV_SCALE_NONE); + } + img->align = align; update_align(obj); @@ -849,9 +854,11 @@ static void update_align(lv_obj_t * obj) if(img->align == LV_IMAGE_ALIGN_STRETCH) { lv_image_set_rotation(obj, 0); lv_image_set_pivot(obj, 0, 0); - int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w; - int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h; - scale_update(obj, scale_x, scale_y); + if(img->w != 0 && img->h != 0) { + int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w; + int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h; + scale_update(obj, scale_x, scale_y); + } } else if(img->align == LV_IMAGE_ALIGN_TILE) { lv_image_set_rotation(obj, 0); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c index 050a62a7c..e781eb397 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c @@ -176,19 +176,19 @@ static const lv_buttonmatrix_ctrl_t default_kb_ctrl_num_map[] = { 1, 1, 1, 1, 1 }; -static const char * * kb_map[10] = { - (const char * *)default_kb_map_lc, - (const char * *)default_kb_map_uc, - (const char * *)default_kb_map_spec, - (const char * *)default_kb_map_num, - (const char * *)default_kb_map_lc, - (const char * *)default_kb_map_lc, - (const char * *)default_kb_map_lc, - (const char * *)default_kb_map_lc, +static const char * const * kb_map[10] = { + default_kb_map_lc, + default_kb_map_uc, + default_kb_map_spec, + default_kb_map_num, + default_kb_map_lc, + default_kb_map_lc, + default_kb_map_lc, + default_kb_map_lc, #if LV_USE_ARABIC_PERSIAN_CHARS == 1 - (const char * *)default_kb_map_ar, + default_kb_map_ar, #endif - (const char * *)NULL + NULL }; static const lv_buttonmatrix_ctrl_t * kb_ctrl[10] = { default_kb_ctrl_lc_map, @@ -269,7 +269,7 @@ void lv_keyboard_set_popovers(lv_obj_t * obj, bool en) lv_keyboard_update_ctrl_map(obj); } -void lv_keyboard_set_map(lv_obj_t * obj, lv_keyboard_mode_t mode, const char * map[], +void lv_keyboard_set_map(lv_obj_t * obj, lv_keyboard_mode_t mode, const char * const map[], const lv_buttonmatrix_ctrl_t ctrl_map[]) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -410,7 +410,7 @@ void lv_keyboard_def_event_cb(lv_event_t * e) } } -const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) +const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb) { return lv_buttonmatrix_get_map(kb); } diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.h b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.h index b315e97cc..f177c1844 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.h @@ -107,7 +107,7 @@ void lv_keyboard_set_popovers(lv_obj_t * kb, bool en); * @param ctrl_map See 'lv_buttonmatrix_set_ctrl_map()' for more info. */ -void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * map[], +void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * const map[], const lv_buttonmatrix_ctrl_t ctrl_map[]); /*===================== @@ -140,7 +140,7 @@ bool lv_keyboard_get_popovers(const lv_obj_t * obj); * @param kb pointer to a keyboard object * @return the current map */ -const char ** lv_keyboard_get_map_array(const lv_obj_t * kb); +const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb); /** * Get the index of the lastly "activated" button by the user (pressed, released, focused etc) diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c index efdb8d81d..b762a1e25 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c @@ -158,13 +158,19 @@ void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_ LV_LOG_INFO("Using %" LV_PRIu32 " pages to make the roller look infinite", roller->inf_page_cnt); size_t opt_len = lv_strlen(options) + 1; /*+1 to add '\n' after option lists*/ - char * opt_extra = lv_malloc(opt_len * roller->inf_page_cnt); + size_t opt_extra_len = opt_len * roller->inf_page_cnt; + if(opt_extra_len == 0) { + /*Prevent write overflow*/ + opt_extra_len = 1; + } + + char * opt_extra = lv_malloc(opt_extra_len); uint32_t i; for(i = 0; i < roller->inf_page_cnt; i++) { lv_strcpy(&opt_extra[opt_len * i], options); opt_extra[opt_len * (i + 1) - 1] = '\n'; } - opt_extra[opt_len * roller->inf_page_cnt - 1] = '\0'; + opt_extra[opt_extra_len - 1] = '\0'; lv_label_set_text(label, opt_extra); lv_free(opt_extra); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c index a6a287e94..c4afb4373 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c @@ -442,7 +442,7 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) /* coords of draw span-txt */ lv_point_t txt_pos; - lv_point_set(&txt_pos, 0, indent); /* first line need add indent */ + lv_point_set(&txt_pos, indent, 0); /* first line need add indent */ lv_span_t * cur_span = lv_ll_get_head(&spans->child_ll); const char * cur_txt = cur_span->txt; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c index 02f1b1614..1958371b3 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c @@ -1403,11 +1403,16 @@ static void draw_placeholder(lv_event_t * e) if(ta->one_line) ph_dsc.flag |= LV_TEXT_FLAG_EXPAND; int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + int32_t right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN); int32_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); + int32_t bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN); int32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN); lv_area_t ph_coords; lv_area_copy(&ph_coords, &obj->coords); - lv_area_move(&ph_coords, left + border_width, top + border_width); + ph_coords.x1 += left + border_width; + ph_coords.x2 -= right + border_width; + ph_coords.y1 += top + border_width; + ph_coords.y2 -= bottom + border_width; ph_dsc.text = ta->placeholder_txt; lv_draw_label(layer, &ph_dsc, &ph_coords); } diff --git a/tasmota/lvgl_berry/tasmota_lv_conf.h b/tasmota/lvgl_berry/tasmota_lv_conf.h index 5fcfcfe82..5b80a8dc7 100644 --- a/tasmota/lvgl_berry/tasmota_lv_conf.h +++ b/tasmota/lvgl_berry/tasmota_lv_conf.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for v9.2.0 + * Configuration file for v9.2.2 */ /* @@ -95,6 +95,14 @@ #if LV_USE_OS == LV_OS_CUSTOM #define LV_OS_CUSTOM_INCLUDE #endif +#if LV_USE_OS == LV_OS_FREERTOS + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ + #define LV_USE_FREERTOS_TASK_NOTIFY 1 +#endif /*======================== * RENDERING CONFIGURATION @@ -205,10 +213,16 @@ #endif /* Use NXP's PXP on iMX RTxxx platforms. */ -#define LV_USE_DRAW_PXP 0 +#define LV_USE_PXP 0 -#if LV_USE_DRAW_PXP - #if LV_USE_OS +#if LV_USE_PXP + /* Use PXP for drawing.*/ + #define LV_USE_DRAW_PXP 1 + + /* Use PXP to rotate display.*/ + #define LV_USE_ROTATE_PXP 0 + + #if LV_USE_DRAW_PXP && LV_USE_OS /* Use additional draw thread for PXP processing.*/ #define LV_USE_PXP_DRAW_THREAD 1 #endif From e30d88e0130bcf676c0c87b2ede598c2f9d1f254 Mon Sep 17 00:00:00 2001 From: smcgann99 <52132596+smcgann99@users.noreply.github.com> Date: Wed, 30 Oct 2024 21:05:57 +0000 Subject: [PATCH 064/205] Update antiburn.be (#22386) Currently anitburn doesn't cover other objects if they are on lv.layer_top, moving it to lv.layer_sys fixes this issue. --- tasmota/berry/modules/antiburn/antiburn.be | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/berry/modules/antiburn/antiburn.be b/tasmota/berry/modules/antiburn/antiburn.be index e695df9ca..2f0a0c3a3 100644 --- a/tasmota/berry/modules/antiburn/antiburn.be +++ b/tasmota/berry/modules/antiburn/antiburn.be @@ -21,7 +21,7 @@ antiburn.init = def (m) lv.start() if self.antiburn == nil - var antiburn = lv.obj(lv.layer_top()) + var antiburn = lv.obj(lv.layer_sys()) antiburn.set_style_radius(0, 0) antiburn.set_style_border_width(0, 0) antiburn.set_style_bg_opa(255, 0) From b89909991c47284e575cc418eced096de77d59b6 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:23:13 +0100 Subject: [PATCH 065/205] `i2c_enabled` refactored as array (#22387) --- CHANGELOG.md | 1 + tasmota/tasmota.ino | 3 +-- tasmota/tasmota_support/support_a_i2c.ino | 4 ++-- tasmota/tasmota_support/support_command.ino | 4 ++-- tasmota/tasmota_support/support_eeprom.ino | 2 +- tasmota/tasmota_support/support_tasmota.ino | 12 ++++++------ tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino | 8 ++++---- .../tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_42_4_i2s_codecs.ino | 4 ++-- tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_wire.ino | 8 ++++---- tasmota/tasmota_xdrv_driver/xdrv_70_1_hdmi_cec.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino | 6 +++--- .../xdrv_81_esp32_webcam_task.ino | 6 +++--- tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino | 2 +- tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino | 2 +- tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino | 2 +- tasmota/tasmota_xdsp_display/xdsp_17_universal.ino | 8 ++++---- tasmota/tasmota_xdsp_display/xdsp_20_tm1650.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_103_sen5x.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino | 2 +- tasmota/tasmota_xx2c_global/xx2c_interface.ino | 4 ++-- 24 files changed, 46 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7d63ad60..e3fd2b4ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. ### Changed - ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) - ESP32 LVGL library from v9.2.0 to v9.2.2 +- `i2c_enabled` refactored as array ### Fixed - ESP32 Arduino Core IPv6 zones used by Matter (#22378) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 6f312516f..297144954 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -312,8 +312,7 @@ struct TasmotaGlobal_t { bool stop_flash_rotate; // Allow flash configuration rotation bool blinkstate; // LED state bool pwm_present; // Any PWM channel configured with SetOption15 0 - bool i2c_enabled; // I2C configured - bool i2c_enabled_2; // I2C configured, second controller, Wire1 + bool i2c_enabled[MAX_I2S]; // I2C configured for all possible buses (1 or 2) #ifdef ESP32 bool ota_factory; // Select safeboot binary #endif diff --git a/tasmota/tasmota_support/support_a_i2c.ino b/tasmota/tasmota_support/support_a_i2c.ino index c857240cd..339b95352 100644 --- a/tasmota/tasmota_support/support_a_i2c.ino +++ b/tasmota/tasmota_support/support_a_i2c.ino @@ -79,14 +79,14 @@ bool I2cBegin(int sda, int scl, uint32_t bus, uint32_t frequency) { } TwoWire& I2cGetWire(uint8_t bus = 0) { - if ((0 == bus) && TasmotaGlobal.i2c_enabled) { + if ((0 == bus) && TasmotaGlobal.i2c_enabled[0]) { #ifdef USE_I2C_BUS2_ESP8266 I2cSetBus(bus); #endif return Wire; } #ifdef USE_I2C_BUS2 - else if ((1 == bus) && TasmotaGlobal.i2c_enabled_2) { + else if ((1 == bus) && TasmotaGlobal.i2c_enabled[1]) { #ifdef USE_I2C_BUS2_ESP8266 I2cSetBus(bus); #endif diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index eb460e7fb..9235f8ea6 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -2752,12 +2752,12 @@ void CmndBatteryPercent(void) { void CmndI2cScan(void) { // I2CScan - Scan bus1 then bus2 bool jsflag = false; - if (TasmotaGlobal.i2c_enabled) { + if (TasmotaGlobal.i2c_enabled[0]) { I2cScan(); jsflag = true; } #ifdef USE_I2C_BUS2 - if (TasmotaGlobal.i2c_enabled_2) { + if (TasmotaGlobal.i2c_enabled[1]) { if (jsflag) { MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, XdrvMailbox.command); } diff --git a/tasmota/tasmota_support/support_eeprom.ino b/tasmota/tasmota_support/support_eeprom.ino index 10828fe16..58678cad7 100644 --- a/tasmota/tasmota_support/support_eeprom.ino +++ b/tasmota/tasmota_support/support_eeprom.ino @@ -39,7 +39,7 @@ void eeprom_readBytes(uint32_t addr, uint32_t len, uint8_t *buff) { } uint32_t eeprom_init(uint32_t size) { - if (TasmotaGlobal.i2c_enabled) { + if (TasmotaGlobal.i2c_enabled[0]) { if (I2cActive(EEPROM_ADDRESS) || I2cSetDevice(EEPROM_ADDRESS)) { // eeprom is present I2cSetActiveFound(EEPROM_ADDRESS, "24C256"); diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino index aa57a47af..f05f1b724 100644 --- a/tasmota/tasmota_support/support_tasmota.ino +++ b/tasmota/tasmota_support/support_tasmota.ino @@ -2234,17 +2234,17 @@ void GpioInit(void) #ifdef USE_I2C /* if (PinUsed(GPIO_I2C_SCL) && PinUsed(GPIO_I2C_SDA)) { - TasmotaGlobal.i2c_enabled = I2cBegin(Pin(GPIO_I2C_SDA), Pin(GPIO_I2C_SCL)); + TasmotaGlobal.i2c_enabled[0] = I2cBegin(Pin(GPIO_I2C_SDA), Pin(GPIO_I2C_SCL)); #ifdef ESP32 - if (TasmotaGlobal.i2c_enabled) { + if (TasmotaGlobal.i2c_enabled[0]) { AddLog(LOG_LEVEL_INFO, PSTR("I2C: Bus1 using GPIO%02d(SCL) and GPIO%02d(SDA)"), Pin(GPIO_I2C_SCL), Pin(GPIO_I2C_SDA)); } #endif } #ifdef ESP32 if (PinUsed(GPIO_I2C_SCL, 1) && PinUsed(GPIO_I2C_SDA, 1)) { - TasmotaGlobal.i2c_enabled_2 = I2cBegin(Pin(GPIO_I2C_SDA, 1), Pin(GPIO_I2C_SCL, 1), 1); - if (TasmotaGlobal.i2c_enabled_2) { + TasmotaGlobal.i2c_enabled[1] = I2cBegin(Pin(GPIO_I2C_SDA, 1), Pin(GPIO_I2C_SCL, 1), 1); + if (TasmotaGlobal.i2c_enabled[1]) { AddLog(LOG_LEVEL_INFO, PSTR("I2C: Bus2 using GPIO%02d(SCL) and GPIO%02d(SDA)"), Pin(GPIO_I2C_SCL, 1), Pin(GPIO_I2C_SDA, 1)); } } @@ -2258,11 +2258,11 @@ void GpioInit(void) if (PinUsed(GPIO_I2C_SCL, bus) && PinUsed(GPIO_I2C_SDA, bus)) { if (I2cBegin(Pin(GPIO_I2C_SDA, bus), Pin(GPIO_I2C_SCL, bus), bus)) { if (0 == bus) { - TasmotaGlobal.i2c_enabled = true; + TasmotaGlobal.i2c_enabled[0] = true; } #ifdef USE_I2C_BUS2 else { - TasmotaGlobal.i2c_enabled_2 = true; + TasmotaGlobal.i2c_enabled[1] = true; } AddLog(LOG_LEVEL_INFO, PSTR("I2C: Bus%d using GPIO%02d(SCL) and GPIO%02d(SDA)"), bus +1, Pin(GPIO_I2C_SCL, bus), Pin(GPIO_I2C_SDA, bus)); #endif // USE_I2C_BUS2 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino index df86f9e6b..3d2e33d84 100755 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino @@ -13213,7 +13213,7 @@ uint32_t script_i2c(uint8_t sel, uint16_t val, uint32_t val1) { Wire1.end(); Wire1.begin(val & 0x7f, val1); glob_script_mem.script_i2c_wire = &Wire1; - TasmotaGlobal.i2c_enabled_2 = true; + TasmotaGlobal.i2c_enabled[1] = true; if (val & 128) { XsnsCall(FUNC_INIT); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino b/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino index 35d3a9ace..0b226468f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino @@ -667,7 +667,7 @@ void CmndFlashDump(void) void CmndI2cWrite(void) { // I2cWrite
,.. - if (TasmotaGlobal.i2c_enabled) { + if (TasmotaGlobal.i2c_enabled[0]) { char* parms = XdrvMailbox.data; uint8_t buffer[100]; uint32_t index = 0; @@ -696,7 +696,7 @@ void CmndI2cWrite(void) void CmndI2cRead(void) { // I2cRead
, - if (TasmotaGlobal.i2c_enabled) { + if (TasmotaGlobal.i2c_enabled[0]) { char* parms = XdrvMailbox.data; uint8_t buffer[100]; uint32_t index = 0; @@ -729,7 +729,7 @@ void CmndI2cRead(void) void CmndI2cStretch(void) { #ifdef ESP8266 - if (TasmotaGlobal.i2c_enabled && (XdrvMailbox.payload > 0)) { + if (TasmotaGlobal.i2c_enabled[0] && (XdrvMailbox.payload > 0)) { Wire.setClockStretchLimit(XdrvMailbox.payload); } ResponseCmndDone(); @@ -738,7 +738,7 @@ void CmndI2cStretch(void) void CmndI2cClock(void) { - if (TasmotaGlobal.i2c_enabled && (XdrvMailbox.payload > 0)) { + if (TasmotaGlobal.i2c_enabled[0] && (XdrvMailbox.payload > 0)) { Wire.setClock(XdrvMailbox.payload); } ResponseCmndDone(); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino index 68cff800f..defca1ed5 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino @@ -117,7 +117,7 @@ void ZigbeeInit(void) #ifdef USE_ZIGBEE_EZSP // Check the I2C EEprom - if (TasmotaGlobal.i2c_enabled) { + if (TasmotaGlobal.i2c_enabled[0]) { Wire.beginTransmission(USE_ZIGBEE_ZBBRIDGE_EEPROM); uint8_t error = Wire.endTransmission(); if (0 == error) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_4_i2s_codecs.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_4_i2s_codecs.ino index c7092475b..a60d43bab 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_42_4_i2s_codecs.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_42_4_i2s_codecs.ino @@ -124,7 +124,7 @@ uint32_t ES8311_init() { } void S3boxInit(void) { - if (TasmotaGlobal.i2c_enabled_2) { + if (TasmotaGlobal.i2c_enabled[1]) { // box lite ES8156_init(); es7243e_init(); @@ -143,7 +143,7 @@ void S3boxInit(void) { #include void W8960_Init1(void) { - if (TasmotaGlobal.i2c_enabled_2) { + if (TasmotaGlobal.i2c_enabled[1]) { if (I2cSetDevice(W8960_ADDR, 1)) { I2cSetActiveFound(W8960_ADDR, "W8960-I2C", 1); W8960_Init(&Wire1); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_wire.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_wire.ino index 9d57c0398..5f5c8c77c 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_wire.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_wire.ino @@ -33,10 +33,10 @@ TwoWire & getWire(bvm *vm) { be_getmember(vm, 1, "bus"); int32_t bus = be_toint(vm, -1); // bus is 1 or 2 be_pop(vm, 1); - if (1 == bus && TasmotaGlobal.i2c_enabled) { + if (1 == bus && TasmotaGlobal.i2c_enabled[0]) { return Wire; #ifdef USE_I2C_BUS2 - } else if (2 == bus && TasmotaGlobal.i2c_enabled_2) { + } else if (2 == bus && TasmotaGlobal.i2c_enabled[1]) { return Wire1; #endif // USE_I2C_BUS2 } else { @@ -50,9 +50,9 @@ bool I2cEnabled(bvm *vm) { be_getmember(vm, 1, "bus"); int32_t bus = be_toint(vm, -1); // bus is 1 or 2 be_pop(vm, 1); - if (1 == bus && TasmotaGlobal.i2c_enabled) { + if (1 == bus && TasmotaGlobal.i2c_enabled[0]) { return true; - } else if (2 == bus && TasmotaGlobal.i2c_enabled_2) { + } else if (2 == bus && TasmotaGlobal.i2c_enabled[1]) { return true; } else { return false; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_70_1_hdmi_cec.ino b/tasmota/tasmota_xdrv_driver/xdrv_70_1_hdmi_cec.ino index 1a00a528c..19b1447ea 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_70_1_hdmi_cec.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_70_1_hdmi_cec.ino @@ -236,7 +236,7 @@ void CmndHDMIType(void) { // The buffer must be allocated to uint8_t[256] by caller // Only checksum is checked bool ReadEdid256(uint8_t *buf) { - if (!TasmotaGlobal.i2c_enabled) { return true; } // abort if I2C is not started + if (!TasmotaGlobal.i2c_enabled[0]) { return true; } // abort if I2C is not started if (I2cReadBuffer(HDMI_EDID_ADDRESS, 0, buf , 128)) { return true; } if (I2cReadBuffer(HDMI_EDID_ADDRESS, 128, buf + 128, 128)) { return true; } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino index 8d6e6f256..37df5bd3f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino @@ -213,11 +213,11 @@ bool WcPinUsed(void) { // } } - AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: i2c_enabled_2: %d"), TasmotaGlobal.i2c_enabled_2); + AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: i2c_enabled_2: %d"), TasmotaGlobal.i2c_enabled[1]); if (!PinUsed(GPIO_WEBCAM_XCLK) || !PinUsed(GPIO_WEBCAM_PCLK) || !PinUsed(GPIO_WEBCAM_VSYNC) || !PinUsed(GPIO_WEBCAM_HREF) || - ((!PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) && !TasmotaGlobal.i2c_enabled_2) // preferred option is to reuse and share I2Cbus 2 + ((!PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) && !TasmotaGlobal.i2c_enabled[1]) // preferred option is to reuse and share I2Cbus 2 ) { pin_used = false; } @@ -383,7 +383,7 @@ uint32_t WcSetup(int32_t fsiz) { config.pin_href = Pin(GPIO_WEBCAM_HREF); // HREF_GPIO_NUM; config.pin_sccb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM; - unset to use shared I2C bus 2 config.pin_sccb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM; - if(TasmotaGlobal.i2c_enabled_2){ // configure SIOD and SIOC as SDA,2 and SCL,2 + if(TasmotaGlobal.i2c_enabled[1]){ // configure SIOD and SIOC as SDA,2 and SCL,2 config.sccb_i2c_port = 1; // reuse initialized bus 2, can be shared now if(config.pin_sccb_sda < 0){ // GPIO_WEBCAM_SIOD must not be set to really make it happen AddLog(LOG_LEVEL_INFO, PSTR("CAM: Use I2C bus2")); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam_task.ino b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam_task.ino index 369df4bda..0b682e6eb 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam_task.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam_task.ino @@ -761,12 +761,12 @@ bool WcPinUsed(void) { } #ifdef WEBCAM_DEV_DEBUG - AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: i2c_enabled_2: %d"), TasmotaGlobal.i2c_enabled_2); + AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: i2c_enabled_2: %d"), TasmotaGlobal.i2c_enabled[1]); #endif if (!PinUsed(GPIO_WEBCAM_XCLK) || !PinUsed(GPIO_WEBCAM_PCLK) || !PinUsed(GPIO_WEBCAM_VSYNC) || !PinUsed(GPIO_WEBCAM_HREF) || - ((!PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) && !TasmotaGlobal.i2c_enabled_2) // preferred option is to reuse and share I2Cbus 2 + ((!PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) && !TasmotaGlobal.i2c_enabled[1]) // preferred option is to reuse and share I2Cbus 2 ) { pin_used = false; } @@ -974,7 +974,7 @@ uint32_t WcSetup(int32_t fsiz) { config.pin_href = Pin(GPIO_WEBCAM_HREF); // HREF_GPIO_NUM; config.pin_sccb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM; - unset to use shared I2C bus 2 config.pin_sccb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM; - if(TasmotaGlobal.i2c_enabled_2){ // configure SIOD and SIOC as SDA,2 and SCL,2 + if(TasmotaGlobal.i2c_enabled[1]){ // configure SIOD and SIOC as SDA,2 and SCL,2 config.sccb_i2c_port = 1; // reuse initialized bus 2, can be shared now if(config.pin_sccb_sda < 0){ // GPIO_WEBCAM_SIOD must not be set to really make it happen #ifdef WEBCAM_DEV_DEBUG diff --git a/tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino b/tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino index c70ac4bb3..e507f00ea 100644 --- a/tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino +++ b/tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino @@ -56,7 +56,7 @@ void LcdInit(uint8_t mode) } void LcdInitDriver(void) { - if (!TasmotaGlobal.i2c_enabled) { return; } + if (!TasmotaGlobal.i2c_enabled[0]) { return; } if (!Settings->display_model) { if (I2cSetDevice(LCD_ADDRESS1)) { diff --git a/tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino b/tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino index d8a6d5fa4..6a312e8f3 100644 --- a/tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino +++ b/tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino @@ -195,7 +195,7 @@ void MatrixInit(uint8_t mode) } void MatrixInitDriver(void) { - if (!TasmotaGlobal.i2c_enabled) { return; } + if (!TasmotaGlobal.i2c_enabled[0]) { return; } mtx_buffer = (char*)(malloc(MTX_MAX_SCREEN_BUFFER)); if (mtx_buffer != nullptr) { diff --git a/tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino b/tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino index faeb738d0..7ad023b83 100644 --- a/tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino +++ b/tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino @@ -148,7 +148,7 @@ void SevensegInit(uint8_t mode) } void SevensegInitDriver(void) { - if (!TasmotaGlobal.i2c_enabled) { return; } + if (!TasmotaGlobal.i2c_enabled[0]) { return; } if (!Settings->display_model) { if (I2cSetDevice(Settings->display_address[0])) { diff --git a/tasmota/tasmota_xdsp_display/xdsp_17_universal.ino b/tasmota/tasmota_xdsp_display/xdsp_17_universal.ino index 5c19209fa..ed4fbf30f 100644 --- a/tasmota/tasmota_xdsp_display/xdsp_17_universal.ino +++ b/tasmota/tasmota_xdsp_display/xdsp_17_universal.ino @@ -176,13 +176,13 @@ Renderer *Init_uDisplay(const char *desc) { replacepin(&cp, Pin(GPIO_OLED_RESET)); if (wire_n == 0) { - if (!TasmotaGlobal.i2c_enabled) { + if (!TasmotaGlobal.i2c_enabled[0]) { I2cBegin(sda, scl); } } #ifdef ESP32 if (wire_n == 1) { - if (!TasmotaGlobal.i2c_enabled_2) { + if (!TasmotaGlobal.i2c_enabled[1]) { I2cBegin(sda, scl, 1); } } @@ -370,13 +370,13 @@ Renderer *Init_uDisplay(const char *desc) { } if (wire_n == 0) { - if (!TasmotaGlobal.i2c_enabled) { + if (!TasmotaGlobal.i2c_enabled[0]) { I2cBegin(sda, scl); } } #ifdef ESP32 if (wire_n == 1) { - if (!TasmotaGlobal.i2c_enabled_2) { + if (!TasmotaGlobal.i2c_enabled[1]) { I2cBegin(sda, scl, 1, 400000); } } diff --git a/tasmota/tasmota_xdsp_display/xdsp_20_tm1650.ino b/tasmota/tasmota_xdsp_display/xdsp_20_tm1650.ino index 9677abf09..c8629fb4f 100644 --- a/tasmota/tasmota_xdsp_display/xdsp_20_tm1650.ino +++ b/tasmota/tasmota_xdsp_display/xdsp_20_tm1650.ino @@ -253,7 +253,7 @@ void TM1650Init(uint8_t mode) \*********************************************************************************************/ void TM1650InitDriver(void) { - if (!TasmotaGlobal.i2c_enabled) { + if (!TasmotaGlobal.i2c_enabled[0]) { return; } diff --git a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino index 4b93265c2..19144d2d9 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino @@ -559,7 +559,7 @@ void BmpShow(bool json) { // BMP280-77 snprintf_P(name, sizeof(name), PSTR("%s%c%02X"), name, IndexSeparator(), bmp_sensors[bmp_idx].bmp_address); #ifdef USE_I2C_BUS2 - if (TasmotaGlobal.i2c_enabled_2) { // Second bus enabled + if (TasmotaGlobal.i2c_enabled[1]) { // Second bus enabled uint8_t bus = bmp_sensors[0].bmp_bus; for (uint32_t i = 1; i < bmp_count; i++) { if (bus != bmp_sensors[i].bmp_bus) { // Different busses diff --git a/tasmota/tasmota_xsns_sensor/xsns_103_sen5x.ino b/tasmota/tasmota_xsns_sensor/xsns_103_sen5x.ino index 7d014bd1a..9040c42ca 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_103_sen5x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_103_sen5x.ino @@ -56,7 +56,7 @@ void sen5x_Init(void) { #ifdef ESP32 if (!I2cSetDevice(SEN5X_ADDRESS, 0)) { DEBUG_SENSOR_LOG(PSTR("Sensirion SEN5X not found, i2c bus 0")); - if (TasmotaGlobal.i2c_enabled_2 ) { + if (TasmotaGlobal.i2c_enabled[1] ) { if(!I2cSetDevice(SEN5X_ADDRESS, 1)) { DEBUG_SENSOR_LOG(PSTR("Sensirion SEN5X not found, i2c bus 1")); return; diff --git a/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino b/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino index 53006b02b..baa8d23a3 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino @@ -200,7 +200,7 @@ void Ads1115Label(char* label, uint32_t maxsize, uint32_t device) { // "ADS1115-48":{"A0":3240,"A1":3235,"A2":3269,"A3":3269},"ADS1115-49":{"A0":3240,"A1":3235,"A2":3269,"A3":3269} snprintf_P(label, maxsize, PSTR("%s%c%02X"), label, IndexSeparator(), Ads1115[device].address); #ifdef USE_I2C_BUS2 - if (TasmotaGlobal.i2c_enabled_2) { // Second bus enabled + if (TasmotaGlobal.i2c_enabled[1]) { // Second bus enabled uint8_t bus = Ads1115[0].bus; for (uint32_t i = 1; i < ads1115_count; i++) { if (bus != Ads1115[i].bus) { // Different busses diff --git a/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino b/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino index 7b8c5bfba..b447fb541 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino @@ -192,7 +192,7 @@ void Sht3xShow(bool json) { if (sht3x_count > 1) { snprintf_P(types, sizeof(types), PSTR("%s%c%02X"), types, IndexSeparator(), sht3x_sensors[idx].address); // "SHT3X-0xXX" #ifdef USE_I2C_BUS2 - if (TasmotaGlobal.i2c_enabled_2) { + if (TasmotaGlobal.i2c_enabled[1]) { for (uint32_t i = 1; i < sht3x_count; i++) { if (sht3x_sensors[0].bus != sht3x_sensors[i].bus) { snprintf_P(types, sizeof(types), PSTR("%s%c%d"), types, IndexSeparator(), sht3x_sensors[idx].bus + 1); // "SHT3X-0xXX-X" diff --git a/tasmota/tasmota_xx2c_global/xx2c_interface.ino b/tasmota/tasmota_xx2c_global/xx2c_interface.ino index 7979886da..cf5fe3543 100644 --- a/tasmota/tasmota_xx2c_global/xx2c_interface.ino +++ b/tasmota/tasmota_xx2c_global/xx2c_interface.ino @@ -413,9 +413,9 @@ const uint8_t kI2cList[] = { /*********************************************************************************************/ bool I2cEnabled(uint32_t i2c_index) { - return ((TasmotaGlobal.i2c_enabled + return ((TasmotaGlobal.i2c_enabled[0] #ifdef USE_I2C_BUS2 - || TasmotaGlobal.i2c_enabled_2 + || TasmotaGlobal.i2c_enabled[1] #endif ) && bitRead(Settings->i2c_drivers[i2c_index / 32], i2c_index % 32)); } From 5892fef63d8d166de3cf904ff44f8c67e6c7cb24 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:18:37 +0100 Subject: [PATCH 066/205] I2C over Serial, preliminary stub (#22388) * I2C over Serial, preliminary stub * Imporve initializer --- CHANGELOG.md | 1 + tasmota/include/tasmota_template.h | 6 + tasmota/language/af_AF.h | 2 + tasmota/language/bg_BG.h | 2 + tasmota/language/ca_AD.h | 2 + tasmota/language/cs_CZ.h | 2 + tasmota/language/de_DE.h | 2 + tasmota/language/el_GR.h | 2 + tasmota/language/en_GB.h | 2 + tasmota/language/es_ES.h | 2 + tasmota/language/fr_FR.h | 2 + tasmota/language/fy_NL.h | 2 + tasmota/language/he_HE.h | 2 + tasmota/language/hu_HU.h | 2 + tasmota/language/it_IT.h | 2 + tasmota/language/ko_KO.h | 2 + tasmota/language/nl_NL.h | 2 + tasmota/language/pl_PL.h | 2 + tasmota/language/pt_BR.h | 2 + tasmota/language/pt_PT.h | 2 + tasmota/language/ro_RO.h | 2 + tasmota/language/ru_RU.h | 2 + tasmota/language/sk_SK.h | 2 + tasmota/language/sv_SE.h | 2 + tasmota/language/tr_TR.h | 2 + tasmota/language/uk_UA.h | 2 + tasmota/language/vi_VN.h | 2 + tasmota/language/zh_CN.h | 2 + tasmota/language/zh_TW.h | 2 + tasmota/tasmota_support/support_a_i2c.ino | 10 ++ .../xdrv_76_serial_i2c.ino | 163 ++++++++++++++++++ 31 files changed, 234 insertions(+) create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_76_serial_i2c.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index e3fd2b4ed..b977f1c98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ## [14.3.0.3] ### Added +- I2C over Serial, preliminary stub ### Breaking Changed diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 5c694d28e..3788d9a8b 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -226,6 +226,7 @@ enum UserSelectablePins { GPIO_BL0906_RX, // BL0906 Serial interface GPIO_DALI_RX_INV, GPIO_DALI_TX_INV, // DALI GPIO_LD2410S_TX, GPIO_LD2410S_RX, // HLK-LD2410S + GPIO_I2C_SER_TX, GPIO_I2C_SER_RX, // I2C via Serial using SC18IM704 protocol (xdrv74) GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage with max 2045 @@ -499,6 +500,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BL0906_RX "|" D_SENSOR_DALI_RX "_i|" D_SENSOR_DALI_TX "_i|" D_SENSOR_LD2410S_TX "|" D_SENSOR_LD2410S_RX "|" + D_SENSOR_I2C_SER_TX "|" D_SENSOR_I2C_SER_RX "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -602,6 +604,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_PCF8574 AGPIO(GPIO_PCF8574_INT), // PCF8574 Interrupt #endif // USE_PCF8574 +#ifdef USE_I2C_SERIAL + AGPIO(GPIO_I2C_SER_TX) + MAX_I2C, // I2C via Serial TX + AGPIO(GPIO_I2C_SER_RX) + MAX_I2C, // I2C via Serial RX +#endif // USE_I2C_SERIAL #endif #if defined(USE_I2S_AUDIO) || defined (USE_I2S) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 49fcb7f03..cad4d22a4 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 00b556988..e633d6cbb 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index c8234cd9f..fe0ffe9f5 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 3e58a9142..6685140f2 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index b0ad57474..c6d46dad0 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index d06e9ed8c..4933d5f37 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index f27ecacd3..2377cd87b 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 2e0f81424..7616129c9 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 19f1088bc..47d768b6f 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCl" #define D_SENSOR_I2C_SDA "I2C SDa" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MClk" #define D_SENSOR_I2S_BCLK "I2S BClk" #define D_SENSOR_I2S_WS_IN "I2S BClk In" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 68f0d7962..1a7e8c27a 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index f56920cff..38289725a 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 51fd05c23..b9e5d5b62 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 5cdee385c..afd0a7eb5 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C - SCL" #define D_SENSOR_I2C_SDA "I2C - SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S - MCLK" #define D_SENSOR_I2S_BCLK "I2S - BCLK" #define D_SENSOR_I2S_WS_IN "I2S - BCLK IN" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 54a986b06..063ff973a 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 8f2f340d1..f253566eb 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index c7d595703..e117468e4 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index daa039322..32a0fed1c 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 74b9fc7a6..2add60210 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 62b2e2c53..7cca75c10 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 04abb790a..8fb70f1e9 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -699,6 +699,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index b5cce5b26..949758bdf 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index f03dc4165..9025ebdbb 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index b790992a9..c1b0b462e 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index fbaa81d83..3ea86116f 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index ea7214335..caa1075ba 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 0d36a5de1..6a1166f9f 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 5d86c6fa4..e6254ce49 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -698,6 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" #define D_SENSOR_I2S_MCLK "I2S MCLK" #define D_SENSOR_I2S_BCLK "I2S BCLK" #define D_SENSOR_I2S_WS_IN "I2S BCLK IN" diff --git a/tasmota/tasmota_support/support_a_i2c.ino b/tasmota/tasmota_support/support_a_i2c.ino index 339b95352..2240a884c 100644 --- a/tasmota/tasmota_support/support_a_i2c.ino +++ b/tasmota/tasmota_support/support_a_i2c.ino @@ -78,19 +78,29 @@ bool I2cBegin(int sda, int scl, uint32_t bus, uint32_t frequency) { return result; } +TwoWire * I2CSerialGetWire(TwoWire * orig_wire, uint8_t bus); + TwoWire& I2cGetWire(uint8_t bus = 0) { if ((0 == bus) && TasmotaGlobal.i2c_enabled[0]) { #ifdef USE_I2C_BUS2_ESP8266 I2cSetBus(bus); #endif +#ifdef USE_I2C_SERIAL + return I2CSerialGetWire(Wire, bus); +#else return Wire; +#endif // USE_I2C_SERIAL } #ifdef USE_I2C_BUS2 else if ((1 == bus) && TasmotaGlobal.i2c_enabled[1]) { #ifdef USE_I2C_BUS2_ESP8266 I2cSetBus(bus); #endif +#ifdef USE_I2C_SERIAL + return I2CSerialGetWire(Wire1, bus); +#else return Wire1; +#endif // USE_I2C_SERIAL } #endif // USE_I2C_BUS2 else { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_76_serial_i2c.ino b/tasmota/tasmota_xdrv_driver/xdrv_76_serial_i2c.ino new file mode 100644 index 000000000..5053803cf --- /dev/null +++ b/tasmota/tasmota_xdrv_driver/xdrv_76_serial_i2c.ino @@ -0,0 +1,163 @@ +/* + xdrv_76_serial_i2c.ino - UART to I2C using SC18IM704 compatible protocol + + Copyright (C) 2024 Stephan Hadinger + + 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_I2C_SERIAL + +#define XDRV_76 76 + +class TwoWireSerial; + +struct { + bool active = false; + uint8_t bus = 0; + uint8_t tx = 0; + uint8_t rx = 0; + TwoWireSerial *WireSerial = nullptr; // replacement object for TwoWire +} i2c_serial; + +class TwoWireSerial : public TwoWire { +protected: + uint8_t tx; + uint8_t rx; + TasmotaSerial *serial; // serial instance to communicate with SC18IM704 +private: +public: + TwoWireSerial(uint8_t bus_num) : tx(-1), rx(-1), serial(nullptr), TwoWire(bus_num) { + AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: TwoWireSerial(%i)", bus_num); + }; + // ~TwoWireSerial() {}; + + bool setPins(int _tx, int _rx) { + if (_tx >= 0 && _rx >= 0) { + tx = _tx; + rx = _rx; + return true; + } + return false; + } + + + // virtual bool begin() + // virtual bool begin(uint8_t address) override{ Serial.printf(">>>>>>> begin\n"); return true; }; + // virtual bool end() = 0; + bool beginSerial() { + AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: beginSerial"); + if (tx >= 0 && rx >= 0) { + serial = new TasmotaSerial(tx, rx); + if (serial) { + serial->begin(115200); + return true; + } + } + return false; + } + + virtual bool setClock(uint32_t freq) override { + AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: setClock(%i) -- ignored", freq); + return true; + } + + virtual void beginTransmission(uint8_t address) override { + AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: beginTransmission(0x%02X)", address); + }; + virtual uint8_t endTransmission(bool stopBit) override { + AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: endTransmission(%i)", stopBit); + return 2; + } + virtual uint8_t endTransmission(void) override { + AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: endTransmission()"); + return 2; + } + + // not used, but redefine to avoid any accidental call + virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit) override { return 0; }; + virtual size_t requestFrom(uint8_t address, size_t len) override { return 0; }; +}; + +// return the original Wire object or the I2C Serial object +TwoWire & I2CSerialGetWire(TwoWire & orig_wire, uint8_t bus) { + if (i2c_serial.active && i2c_serial.bus == bus) { + AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Bus%d %p"), bus +1, i2c_serial.WireSerial); + return *i2c_serial.WireSerial; + } else { + return orig_wire; + } +} + +// Initialize I2C Serial +// - check if I2C serial is configured on some GPIOs +// - configure serial bus +// - register serial bus with Tasmota +void I2CSerialInit(void) { + i2c_serial.active = false; + // check if I2C serial is configured on some GPIOs + for (uint32_t bus = 0; bus < MAX_I2C; bus++) { + if (PinUsed(GPIO_I2C_SER_TX, bus) && PinUsed(GPIO_I2C_SER_RX, bus)) { + if (i2c_serial.active) { + // Error: I2C Serial was already configured on bus 0, we don't accept a second one + AddLog(LOG_LEVEL_ERROR, "I2C: I2C serial can be configured only on 1 bus"); + continue; + } + if (TasmotaGlobal.i2c_enabled[bus]) { + // Error: I2C was already configured with SDA/SCL on this bus + AddLog(LOG_LEVEL_ERROR, "I2C: I2C serial failed on bus %i because SDA/SCL already configured", bus + 1); + } else { + // all good + i2c_serial.bus = bus; + i2c_serial.tx = Pin(GPIO_I2C_SER_TX, bus); + i2c_serial.rx = Pin(GPIO_I2C_SER_RX, bus); + i2c_serial.active = true; + } + } + } + // configure serial bus + if (i2c_serial.active) { + i2c_serial.WireSerial = new TwoWireSerial(1); // TODO is it ok to use UART 1 ? + i2c_serial.WireSerial->setPins(i2c_serial.tx, i2c_serial.rx); + if (i2c_serial.WireSerial->beginSerial()) { + TasmotaGlobal.i2c_enabled[i2c_serial.bus] = true; // enable at Tasmota level + AddLog(LOG_LEVEL_INFO, "I2C: I2C serial configured on GPIO TX %i / RX %i for bus %i", i2c_serial.tx, i2c_serial.rx, i2c_serial.bus + 1); + } else { + delete i2c_serial.WireSerial; + i2c_serial.active = false; + } + } + AddLog(LOG_LEVEL_DEBUG_MORE, "I2C: I2C serial active %i, bus %i, tx %i / rx %i, wire %p", i2c_serial.active, i2c_serial.bus + 1, i2c_serial.tx, i2c_serial.rx, i2c_serial.WireSerial); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv76(uint32_t function) { + bool result = false; + + if (FUNC_PRE_INIT == function) { + I2CSerialInit(); + } else if (i2c_serial.active) { + switch (function) { + case FUNC_ACTIVE: + result = true; + break; + } + } + return result; +} + +#endif // USE_I2C_SERIAL From 789c990c19131cd9cdff96a3d617c94c80526622 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 31 Oct 2024 10:41:18 +0100 Subject: [PATCH 067/205] Fix ESP8266 I2C --- tasmota/tasmota.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 297144954..16191bb1f 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -312,7 +312,7 @@ struct TasmotaGlobal_t { bool stop_flash_rotate; // Allow flash configuration rotation bool blinkstate; // LED state bool pwm_present; // Any PWM channel configured with SetOption15 0 - bool i2c_enabled[MAX_I2S]; // I2C configured for all possible buses (1 or 2) + bool i2c_enabled[2]; // I2C configured for all possible buses (1 or 2) #ifdef ESP32 bool ota_factory; // Select safeboot binary #endif From deca4d9e0623ece4b61309b4ae45af38738f6035 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 31 Oct 2024 10:49:21 +0100 Subject: [PATCH 068/205] Update changelogs --- CHANGELOG.md | 6 +++--- RELEASENOTES.md | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b977f1c98..0a901e3b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,14 +5,14 @@ All notable changes to this project will be documented in this file. ## [14.3.0.3] ### Added -- I2C over Serial, preliminary stub +- Support for I2C over Serial, preliminary stub (#22388) ### Breaking Changed ### Changed - ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) -- ESP32 LVGL library from v9.2.0 to v9.2.2 -- `i2c_enabled` refactored as array +- ESP32 LVGL library from v9.2.0 to v9.2.2 (#22385) +- Refactored `i2c_enabled` as array (#22387) ### Fixed - ESP32 Arduino Core IPv6 zones used by Matter (#22378) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e4ecc9f9e..b20c59033 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -122,6 +122,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliGroup` to add gear to groups - DALI command `DaliTarget` to set light control broadcast, group number or gear number - DALI inverted signal configuration using GPIO DALI RX_i/TX_i +- Support for I2C over Serial, preliminary stub [#22388](https://github.com/arendst/Tasmota/issues/22388) - Support for Shelly DALI Dimmer Gen3 - Support for HLK-LD2410S 24GHz smart wave motion sensor [#22253](https://github.com/arendst/Tasmota/issues/22253) - Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) @@ -138,6 +139,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Changed - ESP32 Platform from 2024.09.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241030 and IDF to 5.3.1.241024 [#22384](https://github.com/arendst/Tasmota/issues/22384) +- ESP32 LVGL library from v9.2.0 to v9.2.2 [#22385](https://github.com/arendst/Tasmota/issues/22385) +- Refactored `i2c_enabled` as array [#22387](https://github.com/arendst/Tasmota/issues/22387) - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default - Shutter optimized behavior to publish shutter data with sensor request [#22353](https://github.com/arendst/Tasmota/issues/22353) From 49d706f54c0b681d46a8bcf3587efd003111854c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:01:36 +0100 Subject: [PATCH 069/205] Add DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight` --- CHANGELOG.md | 16 +- RELEASENOTES.md | 3 +- tasmota/include/tasmota_types.h | 16 +- tasmota/include/tasmota_version.h | 2 +- tasmota/tasmota_support/settings.ino | 3 + .../xdrv_01_9_webserver.ino | 8 +- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 259 +++++++++++++----- 7 files changed, 225 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a901e3b6..0cd6b0ae4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,22 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.3.0.3] +## [14.3.0.4] ### Added -- Support for I2C over Serial, preliminary stub (#22388) +- DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight` ### Breaking Changed +### Changed + +### Fixed + +### Removed + +## [14.3.0.3] 20241031 +### Added +- Support for I2C over Serial, preliminary stub (#22388) + ### Changed - ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) - ESP32 LVGL library from v9.2.0 to v9.2.2 (#22385) @@ -17,8 +27,6 @@ All notable changes to this project will be documented in this file. ### Fixed - ESP32 Arduino Core IPv6 zones used by Matter (#22378) -### Removed - ## [14.3.0.2] 20241030 ### Added - DALI command `DaliGear` to set max found gear to speed up scan response diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b20c59033..a1c8e88f5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -114,13 +114,14 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.3.0.3 +## Changelog v14.3.0.4 ### Added - Command ``SetOption161 1`` to disable web page slider updates by commands - DALI support for short addresses (gear) and groups - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups - DALI command `DaliTarget` to set light control broadcast, group number or gear number +- DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight` - DALI inverted signal configuration using GPIO DALI RX_i/TX_i - Support for I2C over Serial, preliminary stub [#22388](https://github.com/arendst/Tasmota/issues/22388) - Support for Shelly DALI Dimmer Gen3 diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index 41b3a03fb..8752a6ec8 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -195,7 +195,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t mqtt_disable_modbus : 1; // bit 12 (v13.3.0.5) - SetOption158 - (MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead uint32_t counter_both_edges : 1; // bit 13 (v13.3.0.5) - SetOption159 - (Counter) Enable counting on both rising and falling edge (1) uint32_t ld2410_use_pin : 1; // bit 14 (v14.3.0.2) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1) - uint32_t disable_slider_updates : 1; // bit 15 (v14.3.0.2) - SetOption161 - (Light) Disable slider updates (1) + uint32_t disable_slider_updates : 1; // bit 15 (v14.3.0.2) - SetOption161 - (Light) Disable slider updates by commands (1) uint32_t spare16 : 1; // bit 16 uint32_t spare17 : 1; // bit 17 uint32_t spare18 : 1; // bit 18 @@ -260,15 +260,11 @@ typedef union { uint32_t spare16 : 1; // bit 16 uint32_t spare17 : 1; // bit 17 uint32_t spare18 : 1; // bit 18 - uint32_t spare19 : 1; // bit 19 - uint32_t spare20 : 1; // bit 20 - uint32_t spare21 : 1; // bit 21 - uint32_t spare22 : 1; // bit 22 - uint32_t spare23 : 1; // bit 23 - uint32_t FTP_Mode : 2; // bit 24, 25 - uint32_t tariff_forced : 2; // bit 26..27 (v12.4.0.2) - Energy forced tariff : 0=tariff change on time, 1|2=tariff forced - uint32_t sunrise_dawn_angle : 2; // bits 28/29 (v12.1.1.4) - - uint32_t temperature_set_res : 2; // bits 30/31 (v9.3.1.4) - (Tuya) + uint32_t dali_group_sliders : 5; // bit 19.23 (v14.3.0.3) - (DALI) Number of group sliders 0 to 16 + uint32_t FTP_Mode : 2; // bit 24/25 + uint32_t tariff_forced : 2; // bit 26/27 (v12.4.0.2) - Energy forced tariff : 0=tariff change on time, 1|2=tariff forced + uint32_t sunrise_dawn_angle : 2; // bit 28/29 (v12.1.1.4) - + uint32_t temperature_set_res : 2; // bit 30/31 (v9.3.1.4) - (Tuya) }; } SysMBitfield2; diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index fe63d03c4..d49cbe725 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E030003; // 14.3.0.3 +const uint32_t TASMOTA_VERSION = 0x0E030004; // 14.3.0.4 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index b74d7c663..c509f5cba 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -1838,6 +1838,9 @@ void SettingsDelta(void) { if (Settings->version < 0x0E030002) { // 14.3.0.2 Settings->sbflag1.dali_light = 1; } + if (Settings->version < 0x0E030004) { // 14.3.0.4 + Settings->mbflag2.dali_group_sliders = 2; + } Settings->version = TASMOTA_VERSION; SettingsSave(1); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 0382e78a3..a452417ef 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -271,6 +271,9 @@ const char HTTP_MSG_SLIDER_GRADIENT[] PROGMEM = "" ""; +const char HTTP_MSG_SLIDER_UPDATE[] PROGMEM = + "
" D_DEVICE_WILL_RESTART "

"; @@ -1354,7 +1357,7 @@ void HandleRoot(void) WSContentSpaceButton(BUTTON_FIRMWARE_UPGRADE); #endif // ESP32 WSContentButton(BUTTON_CONSOLE); -#else +#else // Not FIRMWARE_MINIMAL WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentButton(BUTTON_INFORMATION); WSContentButton(BUTTON_FIRMWARE_UPGRADE); @@ -1534,7 +1537,8 @@ bool HandleRootStatusRefresh(void) if (current_value != Web.slider[i]) { Web.slider[i] = current_value; // https://stackoverflow.com/questions/4057236/how-to-add-onload-event-to-a-div-element - WSContentSend_P(PSTR(""), i +1, current_value); + WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""), i +1, current_value); } } } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index 4fe44e7a1..7818b0362 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -19,6 +19,8 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 1.1.0.0 20241031 update - Add GUI sliders with feedback when `DaliLight 0` + - Add command `DaliGroupSliders 0..16` to show GUI sliders 1.0.0.2 20241025 update - Fix GPIO detection - Fix ESP32(C3) transmit stability by disabling interrupts 1.0.0.1 20241024 update - Change from signal invert defines to GPIO config DALI RX_i/DALI TX_i @@ -264,6 +266,8 @@ // Address type - Send as first byte #define DALI_BROADCAST_DP 0x00FE // 0b11111110 254 - Broadcast address +#define DALI_MAX_STORED 17 // Store broadcast and group states + #define DALI_TOPIC "DALI" #define D_PRFX_DALI "Dali" @@ -272,14 +276,16 @@ const char kDALICommands[] PROGMEM = D_PRFX_DALI "|" // Prefix #ifdef USE_LIGHT "|Light" #endif // USE_LIGHT - "|Send|Query|Scan|Group|Gear"; + "|Send|Query|Scan|Group" + "|GroupSliders|Gear"; void (* const DALICommand[])(void) PROGMEM = { &CmndDali, &CmndDaliPower, &CmndDaliDimmer, &CmndDaliTarget, #ifdef USE_LIGHT &CmndDaliLight, #endif // USE_LIGHT - &CmndDaliSend, &CmndDaliQuery, &CmndDaliScan, &CmndDaliGroup, &CmndDaliGear }; + &CmndDaliSend, &CmndDaliQuery, &CmndDaliScan, &CmndDaliGroup, + &CmndDaliGroupSliders, &CmndDaliGear }; struct DALI { uint32_t bit_cycles; @@ -290,9 +296,13 @@ struct DALI { uint8_t max_short_address; uint8_t address; uint8_t command; - uint8_t dimmer; + uint8_t last_dimmer; + uint8_t dimmer[DALI_MAX_STORED]; + uint8_t web_dimmer[DALI_MAX_STORED]; uint8_t target; - bool power; + bool last_power; + bool power[DALI_MAX_STORED]; + bool web_power[DALI_MAX_STORED]; bool available; bool response; bool light_sync; @@ -305,23 +315,23 @@ struct DALI { * DALI low level \*********************************************************************************************/ -uint32_t DaliTarget2Address(uint32_t target) { +uint32_t DaliTarget2Address(void) { // 1..64 = Short address // 101..116 = Group address // Others = Broadcast - if ((target >= 1) && (target <= 64)) { // 1 .. 64 - target -= 1; // Short address - target <<= 1; + if ((Dali->target >= 1) && (Dali->target <= 64)) { // 1 .. 64 + Dali->target -= 1; // Short address + Dali->target <<= 1; } - else if ((target >= 101) && (target <= 116)) { // 101 .. 116 - target -= 101; - target <<= 1; - target |= 0x80; // Group address + else if ((Dali->target >= 101) && (Dali->target <= 116)) { // 101 .. 116 + Dali->target -= 101; + Dali->target <<= 1; + Dali->target |= 0x80; // Group address } else { // Others - target = DALI_BROADCAST_DP; // Broadcast address + Dali->target = DALI_BROADCAST_DP; // Broadcast address } - return target &0xFE; // Direct Arc Power Control command + return Dali->target &0xFE; // Direct Arc Power Control command } /* @@ -336,6 +346,34 @@ uint32_t DaliAddress2Target(uint32_t adr) { } */ +uint32_t DaliSaveState(uint32_t adr, uint32_t cmd) { + if (adr &0x01) { return 0; } // No address + int index = -1; + if (DALI_BROADCAST_DP == adr) { // Broadcast address + index = 0; + } + adr >>= 1; + if ((adr >= 0x40) && (adr <= 0x4F)) { // Group address 0 to 15 + index = adr -0x3F; + } + if (index >= 0) { + Dali->last_power = Dali->power[index]; + Dali->power[index] = (cmd); // State + if (Dali->power[index]) { + Dali->last_dimmer = Dali->dimmer[index]; + Dali->dimmer[index] = cmd; // Value + } + if ((0 == index) && !Dali->power[0]) { // Only on Broadcast change to power Off + for (uint32_t i = 0; i < DALI_MAX_STORED; i++) { + Dali->power[i] = false; // Log all group power as Off when Broadcast is Off + } + } + } else { + index = 0; // Use broadcast + } + return index; +} + void DaliEnableRxInterrupt(void) { Dali->available = false; attachInterrupt(Dali->pin_rx, DaliReceiveData, (Dali->invert_rx) ? RISING : FALLING); @@ -508,13 +546,7 @@ void DaliSendData(uint32_t adr, uint32_t cmd) { Dali->address = adr; Dali->command = cmd; - if (DaliTarget2Address(Dali->target) == adr) { - repeat = true; - Dali->power = (cmd); // State - if (Dali->power) { - Dali->dimmer = cmd; // Value - } - } + DaliSaveState(adr, cmd); if (!repeat && (adr &0x01)) { // YAAAAAA1 Commands where user didn't set repeat if ((adr >= 0xA1) && (adr <= 0xFD)) { // Special commands @@ -751,25 +783,28 @@ uint32_t DaliCommission(uint8_t init_arg) { #ifdef USE_LIGHT DaliInitLight(); - uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address(Dali->target) : DALI_BROADCAST_DP; - DaliSendData(address, Dali->power); // Restore lights + uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address() : DALI_BROADCAST_DP; + DaliSendData(address, Dali->power[0]); // Restore lights #else - DaliSendData(DALI_BROADCAST_DP, Dali->power); // Restore lights + DaliSendData(DALI_BROADCAST_DP, Dali->power[0]); // Restore lights #endif // USE_LIGHT return cnt; } /*********************************************************************************************/ -void ResponseAppendDali(void) { - uint8_t dimmer = changeUIntScale(Dali->dimmer, 0, 254, 0, 100); - ResponseAppend_P(PSTR("\"DALI\":{\"Power\":\"%s\",\"Dimmer\":%d,\"Address\":%d,\"Command\":%d}"), - GetStateText(Dali->power), dimmer, Dali->address, Dali->command); +void ResponseAppendDali(uint32_t index) { + char number[12]; + uint8_t dimmer = changeUIntScale(Dali->dimmer[index], 0, 254, 0, 100); + ResponseAppend_P(PSTR("\"DALI\":{\"Power%s\":\"%s\",\"Dimmer%s\":%d,\"Address\":%d,\"Command\":%d}"), + (0==index)?"":itoa(index+100, number, 10), GetStateText(Dali->power[index]), + (0==index)?"":itoa(index+100, number, 10), dimmer, + Dali->address, Dali->command); } -void ResponseDali(void) { +void ResponseDali(uint32_t index) { Response_P(PSTR("{")); - ResponseAppendDali(); + ResponseAppendDali(index); ResponseJsonEnd(); } @@ -787,45 +822,32 @@ void DaliLoop(void) { Dali->address = Dali->received_dali_data >> 8; Dali->command = Dali->received_dali_data; + uint32_t index = DaliSaveState(Dali->address, Dali->command); // Update dimmer and power -#ifdef USE_LIGHT bool show_response = true; - if (DaliTarget2Address(Dali->target) == Dali->address) { - uint8_t dimmer_old = changeUIntScale(Dali->dimmer, 0, 254, 0, 100); - uint8_t power_old = Dali->power; - Dali->power = (Dali->command); // State - if (Dali->power) { - Dali->dimmer = Dali->command; // Value - } +#ifdef USE_LIGHT + if (DaliTarget2Address() == Dali->address) { if (Settings->sbflag1.dali_light) { // DaliLight 1 - uint8_t dimmer_new = changeUIntScale(Dali->dimmer, 0, 254, 0, 100); - if (power_old != Dali->power) { + uint8_t dim_old = changeUIntScale(Dali->last_dimmer, 0, 254, 0, 100); + uint8_t dim_new = changeUIntScale(Dali->dimmer[index], 0, 254, 0, 100); + if (Dali->last_power != Dali->power[index]) { Dali->light_sync = true; // Block local loop - ExecuteCommandPower(LightDevice(), Dali->power, SRC_SWITCH); + ExecuteCommandPower(LightDevice(), Dali->power[index], SRC_SWITCH); } - else if (dimmer_old != dimmer_new) { + else if (dim_old != dim_new) { char scmnd[20]; - snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), dimmer_new); + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), dim_new); Dali->light_sync = true; // Block local loop ExecuteCommand(scmnd, SRC_SWITCH); } show_response = false; } } +#endif // USE_LIGHT if (show_response) { - ResponseDali(); + ResponseDali(index); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_PRFX_DALI)); } -#else - if (DaliTarget2Address(Dali->target) == Dali->address) { - Dali->power = (Dali->command); // State - if (Dali->power) { - Dali->dimmer = Dali->command; // Value - } - } - ResponseDali(); - MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_PRFX_DALI)); -#endif // USE_LIGHT Dali->available = false; } @@ -850,7 +872,7 @@ bool DaliSetChannels(void) { } else { uint8_t value = ((uint8_t*)XdrvMailbox.data)[0]; if (255 == value) { value = 254; } // Max Dali value - DaliSendData(DaliTarget2Address(Dali->target), value); + DaliSendData(DaliTarget2Address(), value); } } return true; @@ -900,7 +922,10 @@ bool DaliInit(void) { #endif // DALI_DEBUG Dali->max_short_address = 64; - Dali->dimmer = DALI_INIT_STATE; + for (uint32_t i = 0; i < DALI_MAX_STORED; i++) { + Dali->dimmer[i] = DALI_INIT_STATE; + } + // Manchester twice 1200 bps = 2400 bps = 417 (protocol 416.76 +/- 10%) us Dali->bit_cycles = ESP.getCpuFreqMHz() * 1000000 / 2400; @@ -983,7 +1008,7 @@ void CmndDali(void) { } DaliJsonParse(); } - ResponseDali(); + ResponseDali(0); } /*-------------------------------------------------------------------------------------------*/ @@ -1010,15 +1035,19 @@ void CmndDaliPower(void) { // DaliPower0 0..254 - Broadcast control (= DaliPower) // DaliPower1 0..254 - Short address 0 control // DaliPower3 0..254 - Short address 2 control + uint32_t index = 0; // Broadcast + if ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116)) { + index = XdrvMailbox.index - 100; // Group1 to 16 + } if (((XdrvMailbox.index >= 0) && (XdrvMailbox.index <= 64)) || ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116))) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 254)) { if (XdrvMailbox.payload <= 2) { if (2 == XdrvMailbox.payload) { - XdrvMailbox.payload = (Dali->power) ? 0 : 1; + XdrvMailbox.payload = (Dali->power[index]) ? 0 : 1; } if (1 == XdrvMailbox.payload) { - XdrvMailbox.payload = Dali->dimmer; + XdrvMailbox.payload = Dali->dimmer[index]; } } uint32_t DALIaddr = DALI_BROADCAST_DP; @@ -1031,7 +1060,7 @@ void CmndDaliPower(void) { DaliSendData(DALIaddr, XdrvMailbox.payload); } } - ResponseDali(); + ResponseDali(index); } void CmndDaliDimmer(void) { @@ -1039,6 +1068,10 @@ void CmndDaliDimmer(void) { // DaliDimmer0 0..100 - Broadcast set power off or dimmer state // DaliDimmer1 0..100 - Short address 0 set power off or dimmer state // DaliDimmer3 0..100 - Short address 2 set power off or dimmer state + uint32_t index = 0; // Broadcast + if ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116)) { + index = XdrvMailbox.index - 100; // Group1 to 16 + } if (((XdrvMailbox.index >= 0) && (XdrvMailbox.index <= 64)) || ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116))) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { @@ -1053,7 +1086,7 @@ void CmndDaliDimmer(void) { DaliSendData(DALIaddr, dimmer); } } - ResponseDali(); + ResponseDali(index); } void CmndDaliGroup(void) { @@ -1169,13 +1202,23 @@ void CmndDaliScan(void) { } } +void CmndDaliGroupSliders(void) { + // DaliGroupSliders 0..16 - Disable light controls and add group sliders + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 16)) { + Settings->sbflag1.dali_light = 0; // Disable DaliLight + Settings->mbflag2.dali_group_sliders = XdrvMailbox.payload; + TasmotaGlobal.restart_flag = 2; // Restart to update GUI + } + ResponseCmndNumber(Settings->mbflag2.dali_group_sliders); +} + #ifdef USE_LIGHT void CmndDaliLight(void) { // DaliLight 0 - Disable light controls // DaliLight 1 - Enable light controls if (XdrvMailbox.data_len > 0) { Settings->sbflag1.dali_light = XdrvMailbox.payload &1; - TasmotaGlobal.restart_flag = 2; + TasmotaGlobal.restart_flag = 2; // Restart to update GUI } ResponseCmndStateText(Settings->sbflag1.dali_light); } @@ -1185,10 +1228,86 @@ void CmndDaliLight(void) { * Presentation \*********************************************************************************************/ +#ifdef USE_WEBSERVER +const char HTTP_MSG_SLIDER_DALI[] PROGMEM = + "
" + "" + "" + ""; + +void DaliWebAddMainSlider(void) { + WSContentSend_P(HTTP_TABLE100); + char number[12]; + uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders; + for (uint32_t i = 0; i < max_sliders; i++) { + Dali->web_dimmer[i] = Dali->dimmer[i]; + Dali->web_power[i] = Dali->power[i]; + WSContentSend_P(HTTP_MSG_SLIDER_DALI, // Brightness - Black to White + i, // k75 + WebColor((Dali->web_power[i])?COL_BUTTON:COL_BACKGROUND), + i, // k75= + (0==i)?"B":"G", // B (Broadcast) or G1 to G16 (Group) + (0==i)?"":itoa(i, number, 10), + i, // i75 + changeUIntScale(Dali->web_dimmer[i], 0, 254, 0, 100), + i // i75 + ); + } + WSContentSend_P(PSTR("
" + "
")); +} + +void DaliWebGetArg(void) { + char tmp[8]; // WebGetArg numbers only + char svalue[32]; // Command and number parameter + char webindex[8]; // WebGetArg name + + uint32_t index; + uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders; + for (uint32_t i = 0; i < max_sliders; i++) { + snprintf_P(webindex, sizeof(webindex), PSTR("i75%d"), i); + WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent + if (strlen(tmp)) { + index = i; + if (index > 0) { index += 100; } // Group + snprintf_P(svalue, sizeof(svalue), PSTR("DaliDimmer%d %s"), index, tmp); + ExecuteWebCommand(svalue); + } + } + WebGetArg(PSTR("k75"), tmp, sizeof(tmp)); + if (strlen(tmp)) { + index = atoi(tmp); + if (index > 0) { index += 100; } // Group + snprintf_P(svalue, sizeof(svalue), PSTR("DaliPower%d 2"), index); + ExecuteWebCommand(svalue); + } +} +#endif // USE_WEBSERVER + void DaliShow(bool json) { if (json) { ResponseAppend_P(PSTR(",")); - ResponseAppendDali(); + ResponseAppendDali(0); +#ifdef USE_WEBSERVER + } else { + uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders; + for (uint32_t i = 0; i < max_sliders; i++) { + if (Dali->power[i] != Dali->web_power[i]) { + Dali->web_power[i] = Dali->power[i]; + WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""), + i, WebColor((Dali->web_power[i])?COL_BUTTON:COL_BACKGROUND)); + WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) + } + if (Dali->dimmer[i] != Dali->web_dimmer[i]) { + Dali->web_dimmer[i] = Dali->dimmer[i]; + WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""), + i, changeUIntScale(Dali->web_dimmer[i], 0, 254, 0, 100)); + WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) + } + } +#endif // USE_WEBSERVER } } @@ -1220,7 +1339,19 @@ bool Xdrv75(uint32_t function) { break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: - DaliShow(false); + if (!Settings->sbflag1.dali_light) { // DaliLight 0 + DaliShow(false); + } + break; + case FUNC_WEB_ADD_MAIN_BUTTON: + if (!Settings->sbflag1.dali_light) { // DaliLight 0 + DaliWebAddMainSlider(); + } + break; + case FUNC_WEB_GET_ARG: + if (!Settings->sbflag1.dali_light) { // DaliLight 0 + DaliWebGetArg(); + } break; #endif // USE_WEBSERVER case FUNC_COMMAND: From a463761090836a30ba1492819ce52f3822722f1c Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Thu, 31 Oct 2024 21:26:18 +0100 Subject: [PATCH 070/205] Update Italian language (#22397) --- tasmota/language/it_IT.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index afd0a7eb5..6f7895b06 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.4.0.1 - Last update 26.10.2024 + * Updated until v9.4.0.1 - Last update 31.10.2024 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -698,8 +698,8 @@ #define D_SENSOR_DS18X20 "DS18x20" #define D_SENSOR_I2C_SCL "I2C - SCL" #define D_SENSOR_I2C_SDA "I2C - SDA" -#define D_SENSOR_I2C_SER_TX "I2C Ser TX" -#define D_SENSOR_I2C_SER_RX "I2C Ser RX" +#define D_SENSOR_I2C_SER_TX "I2C Ser - TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser - RX" #define D_SENSOR_I2S_MCLK "I2S - MCLK" #define D_SENSOR_I2S_BCLK "I2S - BCLK" #define D_SENSOR_I2S_WS_IN "I2S - BCLK IN" From 66d69e09c92d741d9728654ecfef63572fbbdc48 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 31 Oct 2024 22:33:40 +0100 Subject: [PATCH 071/205] add `ESPmDNS` to safeboot `lib_ignore` --- platformio_tasmota32.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 35472e182..1647d9c5f 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -52,6 +52,7 @@ monitor_filters = esp32_exception_decoder [safeboot_flags] lib_ignore = ${esp32_defaults.lib_ignore} + ESPmDNS LinkedList ESP Mail Client IRremoteESP8266 From 2dc5c6e2349207d6fc2004b32e3fb26cd1c78a75 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:23:55 +0100 Subject: [PATCH 072/205] Enable DALI light control if other Tasmota light is enabled --- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 58 ++++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index 7818b0362..ce0e6740d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -19,6 +19,7 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 1.1.0.1 20241101 update - Enable DALI if another light is already claimed 1.1.0.0 20241031 update - Add GUI sliders with feedback when `DaliLight 0` - Add command `DaliGroupSliders 0..16` to show GUI sliders 1.0.0.2 20241025 update - Fix GPIO detection @@ -300,6 +301,7 @@ struct DALI { uint8_t dimmer[DALI_MAX_STORED]; uint8_t web_dimmer[DALI_MAX_STORED]; uint8_t target; + bool allow_light; bool last_power; bool power[DALI_MAX_STORED]; bool web_power[DALI_MAX_STORED]; @@ -648,8 +650,6 @@ uint32_t DaliGearPresent(void) { } void DaliInitLight(void) { - Settings->light_fade = 0; // Use Dali fading - Settings->light_correction = 0; // Use Dali light correction // Taken from Shelly Dali Dimmer ;-) DaliSendData(DALI_DATA_TRANSFER_REGISTER0, DALI_INIT_FADE); // Fade x second DaliSendData(0xFF, DALI_SET_FADE_TIME); @@ -826,7 +826,7 @@ void DaliLoop(void) { bool show_response = true; #ifdef USE_LIGHT - if (DaliTarget2Address() == Dali->address) { + if (Dali->allow_light && (DaliTarget2Address() == Dali->address)) { if (Settings->sbflag1.dali_light) { // DaliLight 1 uint8_t dim_old = changeUIntScale(Dali->last_dimmer, 0, 254, 0, 100); uint8_t dim_new = changeUIntScale(Dali->dimmer[index], 0, 254, 0, 100); @@ -854,15 +854,15 @@ void DaliLoop(void) { /*-------------------------------------------------------------------------------------------*/ -#ifdef USE_LIGHT void DaliEverySecond(void) { - if (Settings->sbflag1.dali_light) { // DaliLight 1 - if (5 == TasmotaGlobal.uptime) { - DaliInitLight(); - } + if (5 == TasmotaGlobal.uptime) { + DaliInitLight(); } } +/*-------------------------------------------------------------------------------------------*/ + +#ifdef USE_LIGHT bool DaliSetChannels(void) { if (Settings->sbflag1.dali_light) { // DaliLight 1 Settings->light_fade = 0; // Use Dali fading @@ -881,7 +881,7 @@ bool DaliSetChannels(void) { /*-------------------------------------------------------------------------------------------*/ -bool DaliInit(void) { +bool DaliInit(uint32_t function) { int pin_tx = -1; bool invert_tx = false; if (PinUsed(GPIO_DALI_TX)) { @@ -910,6 +910,8 @@ bool DaliInit(void) { Dali->pin_rx = pin_rx; Dali->invert_rx = invert_rx; + Dali->allow_light = (FUNC_MODULE_INIT == function); // Light control is possible + AddLog(LOG_LEVEL_INFO, PSTR("DLI: GPIO%d(RX%s) and GPIO%d(TX%s)"), Dali->pin_rx, (Dali->invert_rx)?"i":"", Dali->pin_tx, (Dali->invert_tx)?"i":""); @@ -931,6 +933,9 @@ bool DaliInit(void) { DaliEnableRxInterrupt(); + if (!Dali->allow_light) { + Settings->sbflag1.dali_light = false; // No light control possible + } #ifdef USE_LIGHT if (!Settings->sbflag1.dali_light) { // DaliLight 0 return false; @@ -1203,9 +1208,8 @@ void CmndDaliScan(void) { } void CmndDaliGroupSliders(void) { - // DaliGroupSliders 0..16 - Disable light controls and add group sliders + // DaliGroupSliders 0..16 - Add group sliders if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 16)) { - Settings->sbflag1.dali_light = 0; // Disable DaliLight Settings->mbflag2.dali_group_sliders = XdrvMailbox.payload; TasmotaGlobal.restart_flag = 2; // Restart to update GUI } @@ -1216,7 +1220,7 @@ void CmndDaliGroupSliders(void) { void CmndDaliLight(void) { // DaliLight 0 - Disable light controls // DaliLight 1 - Enable light controls - if (XdrvMailbox.data_len > 0) { + if (Dali->allow_light && (XdrvMailbox.data_len > 0)) { Settings->sbflag1.dali_light = XdrvMailbox.payload &1; TasmotaGlobal.restart_flag = 2; // Restart to update GUI } @@ -1239,8 +1243,7 @@ const char HTTP_MSG_SLIDER_DALI[] PROGMEM = void DaliWebAddMainSlider(void) { WSContentSend_P(HTTP_TABLE100); char number[12]; - uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders; - for (uint32_t i = 0; i < max_sliders; i++) { + for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { Dali->web_dimmer[i] = Dali->dimmer[i]; Dali->web_power[i] = Dali->power[i]; WSContentSend_P(HTTP_MSG_SLIDER_DALI, // Brightness - Black to White @@ -1263,8 +1266,7 @@ void DaliWebGetArg(void) { char webindex[8]; // WebGetArg name uint32_t index; - uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders; - for (uint32_t i = 0; i < max_sliders; i++) { + for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { snprintf_P(webindex, sizeof(webindex), PSTR("i75%d"), i); WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent if (strlen(tmp)) { @@ -1290,8 +1292,7 @@ void DaliShow(bool json) { ResponseAppendDali(0); #ifdef USE_WEBSERVER } else { - uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders; - for (uint32_t i = 0; i < max_sliders; i++) { + for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { if (Dali->power[i] != Dali->web_power[i]) { Dali->web_power[i] = Dali->power[i]; WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // " Date: Sun, 3 Nov 2024 10:40:46 +0100 Subject: [PATCH 074/205] New features for MiElHVAC (#22395) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes * New feature Outdoor Temperature for MiElHVAC * Add Outdoor Temperature * New feature Compressor Frequency for MiElHVAC * Added Outdoor Temperature * Renamed internal properties due typo operating and oprating to operation * New feature Auto Clear Remote Temp for MiElHVAC * This PR add auto clear remote temperature function * This funcion is call on first run and after 10 sec the remote temperature stop refresh its value * Send manually Clear command is also available * change function name, small corrections * added auto clear time configurable using cmnd * Improvements to remote temp, auto clear time for MiElHVAC * Added min = 1000ms and max 600000ms limit to remotetemp auto clear time function * Changed function name to use sam format as other * Added RemoteTemperatureSensor to the sensor * more improvements to auto clear time * Changed RemoteTemperatureSensor to RemoteTemperatureSensorState * Added RemoteTemperatureSensorAutoClearTime to the sensor output * New feature Timers for MiElHVAC * Added Timers to the sensor output: * TimerMode - none, on, off, on_and_off * TimerOn - display time to ON * TimerOnRemaining - display remaining time to ON * TimerOff - display time to OFF * TimerOffRemaining - display remaining time to OFF * New feature for Stage and more for MiElHVAC * Added to sensor output: * Added PrerunStage - on/off, report compressor prepare stage before start working * FanStage - off, quiet, 1, 2, 3 ,4 ,5, report current fan stage * ModeStage - manual(heat, dry, cool, fan_only, heat_isee, dry_isee, cool_isee), auto_fan, auto_heat, auto_cool, report current mode * Renamed Bytes to Settings for raw data * Renamed const UPDATE to SETTINGS * Moved SETTINGS const from miel_hvac_msg_settings to miel_hvac_data_settings * Renamed some functions name to get better code readable * Removed some empty lines * Refactor some structure of code to make more clean and better readable * remove duplicate settings request --- .../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 1443 +++++++++-------- 1 file changed, 754 insertions(+), 689 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index 429e026f9..2635cfee5 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -22,10 +22,10 @@ * Mitsubishi Electric HVAC serial interface \*********************************************************************************************/ -#define XDRV_44 44 +#define XDRV_44 44 #ifndef nitems -#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #endif #ifndef CTASSERT @@ -33,7 +33,7 @@ __attribute__((__unused__)) #endif -#define MIEL_HVAC_LOGNAME "MiElHVAC" +#define MIEL_HVAC_LOGNAME "MiElHVAC" #define D_CMND_MIEL_HVAC_SETFANSPEED "HVACSetFanSpeed" #define D_CMND_MIEL_HVAC_SETMODE "HVACSetMode" @@ -54,85 +54,171 @@ bool remotetemp_clear = true; unsigned long remotetemp_auto_clear_time = 10000; unsigned long remotetemp_last_call_time = 0; -struct miel_hvac_header { - uint8_t start; -#define MIEL_HVAC_H_START 0xfc - uint8_t type; -#define MIEL_HVAC_H_TYPE_UPDATED 0x61 -#define MIEL_HVAC_H_TYPE_DATA 0x62 -#define MIEL_HVAC_H_TYPE_CONNECTED 0x7a - uint8_t middle1; -#define MIEL_HVAC_H_MIDDLE1 0x01 - uint8_t middle2; -#define MIEL_HVAC_H_MIDDLE2 0x30 - uint8_t len; +struct miel_hvac_header +{ + uint8_t start; +#define MIEL_HVAC_H_START 0xfc + uint8_t type; +#define MIEL_HVAC_H_TYPE_UPDATED 0x61 +#define MIEL_HVAC_H_TYPE_DATA 0x62 +#define MIEL_HVAC_H_TYPE_CONNECTED 0x7a + uint8_t middle1; +#define MIEL_HVAC_H_MIDDLE1 0x01 + uint8_t middle2; +#define MIEL_HVAC_H_MIDDLE2 0x30 + uint8_t len; }; -struct miel_hvac_data_settings { - uint8_t _pad1[2]; - uint8_t power; - uint8_t mode; -#define MIEL_HVAC_SETTINGS_MODE_MASK 0x7f - uint8_t temp; - uint8_t fan; - uint8_t vane; - uint8_t prohibit; - uint8_t _pad2[1]; - uint8_t widevane; -#define MIEL_HVAC_SETTTINGS_WIDEVANE_MASK \ - 0x0f - uint8_t temp05; - uint8_t _pad3[2]; - uint8_t airdirection; +struct miel_hvac_data_settings +{ + uint8_t _pad1[2]; + uint8_t power; +#define MIEL_HVAC_SETTINGS_POWER_OFF 0x00 +#define MIEL_HVAC_SETTINGS_POWER_ON 0x01 + uint8_t mode; +#define MIEL_HVAC_SETTINGS_MODE_MASK 0x7f +#define MIEL_HVAC_SETTINGS_MODE_HEAT 0x01 +#define MIEL_HVAC_SETTINGS_MODE_DRY 0x02 +#define MIEL_HVAC_SETTINGS_MODE_COOL 0x03 +#define MIEL_HVAC_SETTINGS_MODE_FAN 0x07 +#define MIEL_HVAC_SETTINGS_MODE_AUTO 0x08 +#define MIEL_HVAC_SETTINGS_MODE_HEAT_ISEE 0x09 +#define MIEL_HVAC_SETTINGS_MODE_DRY_ISEE 0x0a +#define MIEL_HVAC_SETTINGS_MODE_COOL_ISEE 0x0b + uint8_t temp; +#ifndef MIEL_HVAC_SETTINGS_TEMP_MIN +#define MIEL_HVAC_SETTINGS_TEMP_MIN 10 +#endif +#ifndef MIEL_HVAC_SETTINGS_TEMP_MAX +#define MIEL_HVAC_SETTINGS_TEMP_MAX 31 +#endif + uint8_t fan; +#define MIEL_HVAC_SETTINGS_FAN_AUTO 0x00 +#define MIEL_HVAC_SETTINGS_FAN_QUIET 0x01 +#define MIEL_HVAC_SETTINGS_FAN_1 0x02 +#define MIEL_HVAC_SETTINGS_FAN_2 0x03 +#define MIEL_HVAC_SETTINGS_FAN_3 0x05 +#define MIEL_HVAC_SETTINGS_FAN_4 0x06 + uint8_t vane; +#define MIEL_HVAC_SETTINGS_VANE_AUTO 0x00 +#define MIEL_HVAC_SETTINGS_VANE_1 0x01 +#define MIEL_HVAC_SETTINGS_VANE_2 0x02 +#define MIEL_HVAC_SETTINGS_VANE_3 0x03 +#define MIEL_HVAC_SETTINGS_VANE_4 0x04 +#define MIEL_HVAC_SETTINGS_VANE_5 0x05 +#define MIEL_HVAC_SETTINGS_VANE_SWING 0x07 + uint8_t prohibit; +#define MIEL_HVAC_SETTINGS_PROHIBIT_OFF 0x00 +#define MIEL_HVAC_SETTINGS_PROHIBIT_POWER 0x01 +#define MIEL_HVAC_SETTINGS_PROHIBIT_MODE 0x02 +#define MIEL_HVAC_SETTINGS_PROHIBIT_MODE_POWER 0x03 +#define MIEL_HVAC_SETTINGS_PROHIBIT_TEMP 0x04 +#define MIEL_HVAC_SETTINGS_PROHIBIT_TEMP_POWER 0x05 +#define MIEL_HVAC_SETTINGS_PROHIBIT_TEMP_MODE 0x06 +#define MIEL_HVAC_SETTINGS_PROHIBIT_ALL 0x07 + uint8_t _pad2[1]; + uint8_t widevane; +#define MIEL_HVAC_SETTINGS_WIDEVANE_MASK 0x0f +#define MIEL_HVAC_SETTINGS_WIDEVANE_AUTO 0x00 +#define MIEL_HVAC_SETTINGS_WIDEVANE_LL 0x01 +#define MIEL_HVAC_SETTINGS_WIDEVANE_L 0x02 +#define MIEL_HVAC_SETTINGS_WIDEVANE_C 0x03 +#define MIEL_HVAC_SETTINGS_WIDEVANE_R 0x04 +#define MIEL_HVAC_SETTINGS_WIDEVANE_RR 0x05 +#define MIEL_HVAC_SETTINGS_WIDEVANE_LR 0x08 +#define MIEL_HVAC_SETTINGS_WIDEVANE_SWING 0x0c +#define MIEL_HVAC_SETTINGS_WIDEVANE_ADJ 0x80 + uint8_t temp05; + uint8_t _pad3[2]; + uint8_t airdirection; +#define MIEL_HVAC_SETTINGS_AIRDIRECTION_EVEN 0x00 +#define MIEL_HVAC_SETTINGS_AIRDIRECTION_INDIRECT 0x01 +#define MIEL_HVAC_SETTINGS_AIRDIRECTION_DIRECT 0x02 }; -struct miel_hvac_data_roomtemp { - uint8_t _pad1[2]; - uint8_t temp; - uint8_t _pad2[1]; - uint8_t outdoortemp; - uint8_t temp05; - uint8_t settemp; - uint8_t _pad3[3]; - uint8_t operationtime; - uint8_t operationtime1; - uint8_t operationtime2; +struct miel_hvac_data_roomtemp +{ + uint8_t _pad1[2]; + uint8_t temp; + uint8_t _pad2[1]; + uint8_t outdoortemp; + uint8_t temp05; + uint8_t settemp; + uint8_t _pad3[3]; + uint8_t operationtime; + uint8_t operationtime1; + uint8_t operationtime2; }; -struct miel_hvac_data_status { - uint8_t _pad1[2]; - uint8_t compressorfrequency; - uint8_t compressor; -#define MIEL_HVAC_STATUS_COMPRESSOR_OFF 0x00 -#define MIEL_HVAC_STATUS_COMPRESSOR_ON 0x01 - uint8_t operationpower; - uint8_t operationpower1; - uint8_t operationenergy; - uint8_t operationenergy1; +struct miel_hvac_data_timers +{ + uint8_t _pad1[2]; + uint8_t mode; +#define MIEL_HVAC_TIMER_MODE_NONE 0x00 +#define MIEL_HVAC_TIMER_MODE_OFF 0x01 +#define MIEL_HVAC_TIMER_MODE_ON 0x02 +#define MIEL_HVAC_TIMER_MODE_BOTH 0x03 + uint8_t onminutes; + uint8_t offminutes; + uint8_t onminutesremaining; + uint8_t offminutesremaining; }; -struct miel_hvac_data { - uint8_t type; -#define MIEL_HVAC_DATA_T_SETTINGS 0x02 -#define MIEL_HVAC_DATA_T_ROOMTEMP 0x03 -#define MIEL_HVAC_DATA_T_TIMER 0x05 -#define MIEL_HVAC_DATA_T_STATUS 0x06 -#define MIEL_HVAC_DATA_T_STAGE 0x09 +struct miel_hvac_data_status +{ + uint8_t _pad1[2]; + uint8_t compressorfrequency; + uint8_t compressor; +#define MIEL_HVAC_STATUS_COMPRESSOR_OFF 0x00 +#define MIEL_HVAC_STATUS_COMPRESSOR_ON 0x01 + uint8_t operationpower; + uint8_t operationpower1; + uint8_t operationenergy; + uint8_t operationenergy1; +}; - union { - struct miel_hvac_data_settings - settings; - struct miel_hvac_data_roomtemp - roomtemp; - struct miel_hvac_data_status - status; +struct miel_hvac_data_stage +{ + uint8_t _pad1[2]; + uint8_t prerun; +#define MIEL_HVAC_STAGE_PRERUN_OFF 0x00 +#define MIEL_HVAC_STAGE_PRERUN_ON 0x04 + uint8_t fan; +#define MIEL_HVAC_STAGE_FAN_OFF 0x00 +#define MIEL_HVAC_STAGE_FAN_1 0x01 +#define MIEL_HVAC_STAGE_FAN_2 0x02 +#define MIEL_HVAC_STAGE_FAN_3 0x03 +#define MIEL_HVAC_STAGE_FAN_4 0x04 +#define MIEL_HVAC_STAGE_FAN_5 0x05 +#define MIEL_HVAC_STAGE_FAN_QUIT 0x06 + uint8_t mode; +#define MIEL_HVAC_STAGE_MODE_MANUAL 0x00 +#define MIEL_HVAC_STAGE_MODE_AUTO_FAN 0x01 +#define MIEL_HVAC_STAGE_MODE_AUTO_HEAT 0x02 +#define MIEL_HVAC_STAGE_MODE_AUTO_COOL 0x03 +}; - uint8_t bytes[15]; - } data; +struct miel_hvac_data +{ + uint8_t type; +#define MIEL_HVAC_DATA_T_SETTINGS 0x02 +#define MIEL_HVAC_DATA_T_ROOMTEMP 0x03 +#define MIEL_HVAC_DATA_T_TIMERS 0x05 +#define MIEL_HVAC_DATA_T_STATUS 0x06 +#define MIEL_HVAC_DATA_T_STAGE 0x09 + + union + { + struct miel_hvac_data_settings settings; + struct miel_hvac_data_roomtemp roomtemp;; + struct miel_hvac_data_timers timers; + struct miel_hvac_data_status status; + struct miel_hvac_data_stage stage; + uint8_t bytes[15]; + } data; }; CTASSERT(sizeof(struct miel_hvac_data) == 16); - CTASSERT(offsetof(struct miel_hvac_data, data.settings.power) == 3); CTASSERT(offsetof(struct miel_hvac_data, data.settings.mode) == 4); CTASSERT(offsetof(struct miel_hvac_data, data.settings.temp) == 5); @@ -151,6 +237,16 @@ CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime) == 11); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime1) == 12); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime2) == 13); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.mode) == 3); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.onminutes) == 4); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.offminutes) == 5); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.onminutesremaining) == 6); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.offminutesremaining) == 7); + +CTASSERT(offsetof(struct miel_hvac_data, data.stage.prerun) == 3); +CTASSERT(offsetof(struct miel_hvac_data, data.stage.fan) == 4); +CTASSERT(offsetof(struct miel_hvac_data, data.stage.mode) == 5); + CTASSERT(offsetof(struct miel_hvac_data, data.status.compressorfrequency) == 3); CTASSERT(offsetof(struct miel_hvac_data, data.status.compressor) == 4); CTASSERT(offsetof(struct miel_hvac_data, data.status.operationpower) == 5); @@ -160,143 +256,100 @@ CTASSERT(offsetof(struct miel_hvac_data, data.status.operationenergy1) == 8); /* to hvac */ -#define MIEL_HVAC_H_TYPE_CONNECT 0x5a -static const uint8_t miel_hvac_msg_connect[] = { 0xca, 0x01 }; +#define MIEL_HVAC_H_TYPE_CONNECT 0x5a +static const uint8_t miel_hvac_msg_connect[] = {0xca, 0x01}; -#define MIEL_HVAC_H_TYPE_REQUEST 0x42 +#define MIEL_HVAC_H_TYPE_REQUEST 0x42 -struct miel_hvac_msg_request { - uint8_t type; -#define MIEL_HVAC_REQUEST_SETTINGS 0x02 -#define MIEL_HVAC_REQUEST_ROOMTEMP 0x03 -#define MIEL_HVAC_REQUEST_TIMERS 0x05 -#define MIEL_HVAC_REQUEST_STATUS 0x06 -#define MIEL_HVAC_REQUEST_STAGE 0x09 - uint8_t zero[15]; +struct miel_hvac_msg_request +{ + uint8_t type; +#define MIEL_HVAC_REQUEST_SETTINGS 0x02 +#define MIEL_HVAC_REQUEST_ROOMTEMP 0x03 +#define MIEL_HVAC_REQUEST_TIMERS 0x05 +#define MIEL_HVAC_REQUEST_STATUS 0x06 +#define MIEL_HVAC_REQUEST_STAGE 0x09 + uint8_t zero[15]; }; -#define MIEL_HVAC_H_TYPE_UPDATE 0x41 +#define MIEL_HVAC_H_TYPE_UPDATE 0x41 -struct miel_hvac_msg_update { - uint8_t one; - uint16_t flags; -#define MIEL_HVAC_UPDATE_F_WIDEVANE (1 << 0) -#define MIEL_HVAC_UPDATE_F_POWER (1 << 8) -#define MIEL_HVAC_UPDATE_F_MODE (1 << 9) -#define MIEL_HVAC_UPDATE_F_TEMP (1 << 10) -#define MIEL_HVAC_UPDATE_F_FAN (1 << 11) -#define MIEL_HVAC_UPDATE_F_VANE (1 << 12) -#define MIEL_HVAC_UPDATE_F_PROHIBIT (1 << 13) -#define MIEL_HVAC_UPDATE_F_AIRDIRECTION (1 << 14) - uint8_t power; -#define MIEL_HVAC_UPDATE_POWER_OFF 0x00 -#define MIEL_HVAC_UPDATE_POWER_ON 0x01 - uint8_t mode; -#define MIEL_HVAC_UPDATE_MODE_HEAT 0x01 -#define MIEL_HVAC_UPDATE_MODE_DRY 0x02 -#define MIEL_HVAC_UPDATE_MODE_COOL 0x03 -#define MIEL_HVAC_UPDATE_MODE_FAN 0x07 -#define MIEL_HVAC_UPDATE_MODE_AUTO 0x08 -#define MIEL_HVAC_UPDATE_MODE_HEAT_ISEE 0x09 -#define MIEL_HVAC_UPDATE_MODE_DRY_ISEE 0x0a -#define MIEL_HVAC_UPDATE_MODE_COOL_ISEE 0x0b - uint8_t temp; -#ifndef MIEL_HVAC_UPDATE_TEMP_MIN -#define MIEL_HVAC_UPDATE_TEMP_MIN 10 -#endif -#ifndef MIEL_HVAC_UPDATE_TEMP_MAX -#define MIEL_HVAC_UPDATE_TEMP_MAX 31 -#endif - uint8_t fan; -#define MIEL_HVAC_UPDATE_FAN_AUTO 0x00 -#define MIEL_HVAC_UPDATE_FAN_QUIET 0x01 -#define MIEL_HVAC_UPDATE_FAN_1 0x02 -#define MIEL_HVAC_UPDATE_FAN_2 0x03 -#define MIEL_HVAC_UPDATE_FAN_3 0x05 -#define MIEL_HVAC_UPDATE_FAN_4 0x06 - uint8_t vane; -#define MIEL_HVAC_UPDATE_VANE_AUTO 0x00 -#define MIEL_HVAC_UPDATE_VANE_1 0x01 -#define MIEL_HVAC_UPDATE_VANE_2 0x02 -#define MIEL_HVAC_UPDATE_VANE_3 0x03 -#define MIEL_HVAC_UPDATE_VANE_4 0x04 -#define MIEL_HVAC_UPDATE_VANE_5 0x05 -#define MIEL_HVAC_UPDATE_VANE_SWING 0x07 - uint8_t prohibit; -#define MIEL_HVAC_UPDATE_PROHIBIT_OFF 0x00 -#define MIEL_HVAC_UPDATE_PROHIBIT_POWER 0x01 -#define MIEL_HVAC_UPDATE_PROHIBIT_MODE 0x02 -#define MIEL_HVAC_UPDATE_PROHIBIT_MODE_POWER 0x03 -#define MIEL_HVAC_UPDATE_PROHIBIT_TEMP 0x04 -#define MIEL_HVAC_UPDATE_PROHIBIT_TEMP_POWER 0x05 -#define MIEL_HVAC_UPDATE_PROHIBIT_TEMP_MODE 0x06 -#define MIEL_HVAC_UPDATE_PROHIBIT_ALL 0x07 - uint8_t _pad1[4]; - uint8_t widevane; -#define MIEL_HVAC_UPDATE_WIDEVANE_MASK 0x0f -#define MIEL_HVAC_UPDATE_WIDEVANE_AUTO 0x00 -#define MIEL_HVAC_UPDATE_WIDEVANE_LL 0x01 -#define MIEL_HVAC_UPDATE_WIDEVANE_L 0x02 -#define MIEL_HVAC_UPDATE_WIDEVANE_C 0x03 -#define MIEL_HVAC_UPDATE_WIDEVANE_R 0x04 -#define MIEL_HVAC_UPDATE_WIDEVANE_RR 0x05 -#define MIEL_HVAC_UPDATE_WIDEVANE_LR 0x08 -#define MIEL_HVAC_UPDATE_WIDEVANE_SWING 0x0c -#define MIEL_HVAC_UPDATE_WIDEVANE_ADJ 0x80 - uint8_t temp05; - uint8_t airdirection; -#define MIEL_HVAC_UPDATE_AIRDIRECTION_EVEN 0x00 -#define MIEL_HVAC_UPDATE_AIRDIRECTION_INDIRECT 0x01 -#define MIEL_HVAC_UPDATE_AIRDIRECTION_DIRECT 0x02 +struct miel_hvac_msg_update_settings +{ + uint8_t one; + uint16_t flags; +#define MIEL_HVAC_SETTINGS_F_WIDEVANE (1 << 0) +#define MIEL_HVAC_SETTINGS_F_POWER (1 << 8) +#define MIEL_HVAC_SETTINGS_F_MODE (1 << 9) +#define MIEL_HVAC_SETTINGS_F_TEMP (1 << 10) +#define MIEL_HVAC_SETTINGS_F_FAN (1 << 11) +#define MIEL_HVAC_SETTINGS_F_VANE (1 << 12) +#define MIEL_HVAC_SETTINGS_F_PROHIBIT (1 << 13) +#define MIEL_HVAC_SETTINGS_F_AIRDIRECTION (1 << 14) + uint8_t power; + uint8_t mode; + uint8_t temp; + uint8_t fan; + uint8_t vane; + uint8_t prohibit; + uint8_t _pad1[4]; + uint8_t widevane; + uint8_t temp05; + uint8_t airdirection; } __packed; -CTASSERT(sizeof(struct miel_hvac_msg_update) == 16); +CTASSERT(sizeof(struct miel_hvac_msg_update_settings) == 16); #define MIEL_HVAC_OFFS(_v) ((_v) - sizeof(struct miel_hvac_header)) -CTASSERT(offsetof(struct miel_hvac_msg_update, flags) == MIEL_HVAC_OFFS(6)); -CTASSERT(offsetof(struct miel_hvac_msg_update, power) == MIEL_HVAC_OFFS(8)); -CTASSERT(offsetof(struct miel_hvac_msg_update, mode) == MIEL_HVAC_OFFS(9)); -CTASSERT(offsetof(struct miel_hvac_msg_update, temp) == MIEL_HVAC_OFFS(10)); -CTASSERT(offsetof(struct miel_hvac_msg_update, fan) == MIEL_HVAC_OFFS(11)); -CTASSERT(offsetof(struct miel_hvac_msg_update, vane) == MIEL_HVAC_OFFS(12)); -CTASSERT(offsetof(struct miel_hvac_msg_update, prohibit) == MIEL_HVAC_OFFS(13)); -CTASSERT(offsetof(struct miel_hvac_msg_update, widevane) == MIEL_HVAC_OFFS(18)); -CTASSERT(offsetof(struct miel_hvac_msg_update, temp05) == MIEL_HVAC_OFFS(19)); -CTASSERT(offsetof(struct miel_hvac_msg_update, airdirection) == MIEL_HVAC_OFFS(20)); - +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, flags) == MIEL_HVAC_OFFS(6)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, power) == MIEL_HVAC_OFFS(8)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, mode) == MIEL_HVAC_OFFS(9)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, temp) == MIEL_HVAC_OFFS(10)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, fan) == MIEL_HVAC_OFFS(11)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, vane) == MIEL_HVAC_OFFS(12)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, prohibit) == MIEL_HVAC_OFFS(13)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, widevane) == MIEL_HVAC_OFFS(18)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, temp05) == MIEL_HVAC_OFFS(19)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, airdirection) == MIEL_HVAC_OFFS(20)); static inline uint8_t miel_hvac_deg2temp(float deg) { - if (!temp_type) { + if (!temp_type) + { return (31 - deg); } - else { - deg = 2*deg + 128; - return ((uint8_t) deg); + else + { + deg = 2 * deg + 128; + return ((uint8_t)deg); } } static inline float miel_hvac_temp2deg(uint8_t temp) { - if (!temp_type) { + if (!temp_type) + { return (31 - temp); } - else { + else + { temp -= 128; - return ((float) temp/2); + return ((float)temp / 2); } } static inline float miel_hvac_roomtemp2deg(uint8_t roomtemp) { - if (!temp_type) { + if (!temp_type) + { return ((unsigned int)roomtemp + 10); } - else { + else + { roomtemp -= 128; - return ((float) roomtemp/2); + return ((float)roomtemp / 2); } } @@ -304,29 +357,30 @@ static inline float miel_hvac_outdoortemp2deg(uint8_t outdoortemp) { outdoortemp -= 128; - return ((float) outdoortemp/2); + return ((float)outdoortemp / 2); } -struct miel_hvac_msg_remotetemp { - uint8_t seven; - uint8_t control; -#define MIEL_HVAC_REMOTETEMP_CLR 0x00 -#define MIEL_HVAC_REMOTETEMP_SET 0x01 +struct miel_hvac_msg_update_remotetemp +{ + uint8_t seven; + uint8_t control; +#define MIEL_HVAC_REMOTETEMP_CLR 0x00 +#define MIEL_HVAC_REMOTETEMP_SET 0x01 /* setting for older units expressed as .5C units starting at 8C */ - uint8_t temp_old; -#define MIEL_HVAC_REMOTETEMP_OLD_MIN 8 -#define MIEL_HVAC_REMOTETEMP_OLD_MAX 38 -#define MIEL_HVAC_REMOTETEMP_OLD_FACTOR 2 + uint8_t temp_old; +#define MIEL_HVAC_REMOTETEMP_OLD_MIN 8 +#define MIEL_HVAC_REMOTETEMP_OLD_MAX 38 +#define MIEL_HVAC_REMOTETEMP_OLD_FACTOR 2 /* setting for newer units expressed as .5C units starting at -63C */ - uint8_t temp; -#define MIEL_HVAC_REMOTETEMP_MIN -63 -#define MIEL_HVAC_REMOTETEMP_MAX 63 -#define MIEL_HVAC_REMOTETEMP_OFFSET 64 -#define MIEL_HVAC_REMOTETEMP_FACTOR 2 - uint8_t _pad2[12]; + uint8_t temp; +#define MIEL_HVAC_REMOTETEMP_MIN -63 +#define MIEL_HVAC_REMOTETEMP_MAX 63 +#define MIEL_HVAC_REMOTETEMP_OFFSET 64 +#define MIEL_HVAC_REMOTETEMP_FACTOR 2 + uint8_t _pad2[12]; }; -CTASSERT(sizeof(struct miel_hvac_msg_remotetemp) == 16); +CTASSERT(sizeof(struct miel_hvac_msg_update_remotetemp) == 16); static inline uint8_t miel_hvac_cksum_fini(uint8_t sum) @@ -334,80 +388,111 @@ miel_hvac_cksum_fini(uint8_t sum) return (0xfc - sum); } -struct miel_hvac_map { - uint8_t byte; - const char *name; +struct miel_hvac_map +{ + uint8_t byte; + const char *name; }; static const struct miel_hvac_map miel_hvac_power_map[] = { - { MIEL_HVAC_UPDATE_POWER_OFF, "off" }, - { MIEL_HVAC_UPDATE_POWER_ON, "on" }, + {MIEL_HVAC_SETTINGS_POWER_OFF, "off"}, + {MIEL_HVAC_SETTINGS_POWER_ON, "on"}, }; static const struct miel_hvac_map miel_hvac_mode_map[] = { - { MIEL_HVAC_UPDATE_MODE_HEAT, "heat" }, - { MIEL_HVAC_UPDATE_MODE_DRY, "dry" }, - { MIEL_HVAC_UPDATE_MODE_COOL, "cool" }, - { MIEL_HVAC_UPDATE_MODE_FAN, "fan_only" }, - { MIEL_HVAC_UPDATE_MODE_AUTO, "auto" }, - { MIEL_HVAC_UPDATE_MODE_HEAT_ISEE, "heat_isee" }, - { MIEL_HVAC_UPDATE_MODE_DRY_ISEE, "dry_isee" }, - { MIEL_HVAC_UPDATE_MODE_COOL_ISEE, "cool_isee" }, + {MIEL_HVAC_SETTINGS_MODE_HEAT, "heat"}, + {MIEL_HVAC_SETTINGS_MODE_DRY, "dry"}, + {MIEL_HVAC_SETTINGS_MODE_COOL, "cool"}, + {MIEL_HVAC_SETTINGS_MODE_FAN, "fan_only"}, + {MIEL_HVAC_SETTINGS_MODE_AUTO, "auto"}, + {MIEL_HVAC_SETTINGS_MODE_HEAT_ISEE, "heat_isee"}, + {MIEL_HVAC_SETTINGS_MODE_DRY_ISEE, "dry_isee"}, + {MIEL_HVAC_SETTINGS_MODE_COOL_ISEE, "cool_isee"}, }; static const struct miel_hvac_map miel_hvac_fan_map[] = { - { MIEL_HVAC_UPDATE_FAN_AUTO, "auto" }, - { MIEL_HVAC_UPDATE_FAN_QUIET, "quiet" }, - { MIEL_HVAC_UPDATE_FAN_1, "1" }, - { MIEL_HVAC_UPDATE_FAN_2, "2" }, - { MIEL_HVAC_UPDATE_FAN_3, "3" }, - { MIEL_HVAC_UPDATE_FAN_4, "4" }, + {MIEL_HVAC_SETTINGS_FAN_AUTO, "auto"}, + {MIEL_HVAC_SETTINGS_FAN_QUIET, "quiet"}, + {MIEL_HVAC_SETTINGS_FAN_1, "1"}, + {MIEL_HVAC_SETTINGS_FAN_2, "2"}, + {MIEL_HVAC_SETTINGS_FAN_3, "3"}, + {MIEL_HVAC_SETTINGS_FAN_4, "4"}, }; static const struct miel_hvac_map miel_hvac_vane_map[] = { - { MIEL_HVAC_UPDATE_VANE_AUTO, "auto" }, - { MIEL_HVAC_UPDATE_VANE_1, "up" }, - { MIEL_HVAC_UPDATE_VANE_2, "up_middle" }, - { MIEL_HVAC_UPDATE_VANE_3, "center" }, - { MIEL_HVAC_UPDATE_VANE_4, "down_middle" }, - { MIEL_HVAC_UPDATE_VANE_5, "down" }, - { MIEL_HVAC_UPDATE_VANE_SWING, "swing" }, + {MIEL_HVAC_SETTINGS_VANE_AUTO, "auto"}, + {MIEL_HVAC_SETTINGS_VANE_1, "up"}, + {MIEL_HVAC_SETTINGS_VANE_2, "up_middle"}, + {MIEL_HVAC_SETTINGS_VANE_3, "center"}, + {MIEL_HVAC_SETTINGS_VANE_4, "down_middle"}, + {MIEL_HVAC_SETTINGS_VANE_5, "down"}, + {MIEL_HVAC_SETTINGS_VANE_SWING, "swing"}, }; static const struct miel_hvac_map miel_hvac_widevane_map[] = { - { MIEL_HVAC_UPDATE_WIDEVANE_AUTO, "auto" }, - { MIEL_HVAC_UPDATE_WIDEVANE_LL, "left" }, - { MIEL_HVAC_UPDATE_WIDEVANE_L, "left_middle" }, - { MIEL_HVAC_UPDATE_WIDEVANE_C, "center" }, - { MIEL_HVAC_UPDATE_WIDEVANE_R, "right" }, - { MIEL_HVAC_UPDATE_WIDEVANE_RR, "right_middle" }, - { MIEL_HVAC_UPDATE_WIDEVANE_LR, "split" }, - { MIEL_HVAC_UPDATE_WIDEVANE_SWING, "swing" }, + {MIEL_HVAC_SETTINGS_WIDEVANE_AUTO, "auto"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_LL, "left"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_L, "left_middle"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_C, "center"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_R, "right"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_RR, "right_middle"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_LR, "split"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_SWING, "swing"}, }; static const struct miel_hvac_map miel_hvac_prohibit_map[] = { - { MIEL_HVAC_UPDATE_PROHIBIT_OFF, "off" }, - { MIEL_HVAC_UPDATE_PROHIBIT_POWER, "power" }, - { MIEL_HVAC_UPDATE_PROHIBIT_MODE, "mode" }, - { MIEL_HVAC_UPDATE_PROHIBIT_MODE_POWER, "mode_power" }, - { MIEL_HVAC_UPDATE_PROHIBIT_TEMP, "temp" }, - { MIEL_HVAC_UPDATE_PROHIBIT_TEMP_POWER, "temp_power" }, - { MIEL_HVAC_UPDATE_PROHIBIT_TEMP_MODE, "temp_mode" }, - { MIEL_HVAC_UPDATE_PROHIBIT_ALL, "all" }, + {MIEL_HVAC_SETTINGS_PROHIBIT_OFF, "off"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_POWER, "power"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_MODE, "mode"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_MODE_POWER, "mode_power"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_TEMP, "temp"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_TEMP_POWER, "temp_power"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_TEMP_MODE, "temp_mode"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_ALL, "all"}, }; static const struct miel_hvac_map miel_hvac_airdirection_map[] = { - { MIEL_HVAC_UPDATE_AIRDIRECTION_EVEN, "even" }, - { MIEL_HVAC_UPDATE_AIRDIRECTION_INDIRECT, "indirect" }, - { MIEL_HVAC_UPDATE_AIRDIRECTION_DIRECT, "direct" }, + {MIEL_HVAC_SETTINGS_AIRDIRECTION_EVEN, "even"}, + {MIEL_HVAC_SETTINGS_AIRDIRECTION_INDIRECT, "indirect"}, + {MIEL_HVAC_SETTINGS_AIRDIRECTION_DIRECT, "direct"}, }; static const struct miel_hvac_map miel_hvac_compressor_map[] = { - { MIEL_HVAC_STATUS_COMPRESSOR_OFF, "off" }, - { MIEL_HVAC_STATUS_COMPRESSOR_ON, "on" }, + {MIEL_HVAC_STATUS_COMPRESSOR_OFF, "off"}, + {MIEL_HVAC_STATUS_COMPRESSOR_ON, "on"}, }; -enum miel_hvac_parser_state { +static const struct miel_hvac_map miel_hvac_timer_mode_map[] = { + {MIEL_HVAC_TIMER_MODE_NONE, "none"}, + {MIEL_HVAC_TIMER_MODE_OFF, "off"}, + {MIEL_HVAC_TIMER_MODE_ON, "on"}, + {MIEL_HVAC_TIMER_MODE_BOTH, "on_and_off"}, +}; + +static const struct miel_hvac_map miel_hvac_stage_prerun_map[] = { + {MIEL_HVAC_STAGE_PRERUN_OFF, "off"}, + {MIEL_HVAC_STAGE_PRERUN_ON, "on"}, +}; + +static const struct miel_hvac_map miel_hvac_stage_fan_map[] = { + {MIEL_HVAC_STAGE_FAN_OFF, "off"}, + {MIEL_HVAC_STAGE_FAN_QUIT, "quiet"}, + {MIEL_HVAC_STAGE_FAN_1, "1"}, + {MIEL_HVAC_STAGE_FAN_2, "2"}, + {MIEL_HVAC_STAGE_FAN_3, "3"}, + {MIEL_HVAC_STAGE_FAN_4, "4"}, + {MIEL_HVAC_STAGE_FAN_5, "5"}, +}; + +static const struct miel_hvac_map miel_hvac_stage_mode_map[] = { + {MIEL_HVAC_STAGE_MODE_MANUAL, "manual"}, + {MIEL_HVAC_STAGE_MODE_AUTO_FAN, "auto_fan"}, + {MIEL_HVAC_STAGE_MODE_AUTO_HEAT, "auto_heat"}, + {MIEL_HVAC_STAGE_MODE_AUTO_COOL, "auto_cool"}, +}; + +enum miel_hvac_parser_state +{ MIEL_HVAC_P_START, MIEL_HVAC_P_TYPE, MIEL_HVAC_P_MIDDLE1, @@ -415,60 +500,55 @@ enum miel_hvac_parser_state { MIEL_HVAC_P_LEN, MIEL_HVAC_P_DATA, MIEL_HVAC_P_CKSUM, - MIEL_HVAC_P_SKIP, MIEL_HVAC_P_SKIP_CKSUM, }; -#define MIEL_HVAC_DATABUFLEN 64 +#define MIEL_HVAC_DATABUFLEN 64 -struct miel_hvac_parser { - enum miel_hvac_parser_state - p_state; - uint8_t p_tmo; - uint8_t p_type; - uint8_t p_sum; - uint8_t p_len; - uint8_t p_off; - uint8_t p_data[MIEL_HVAC_DATABUFLEN]; +struct miel_hvac_parser +{ + enum miel_hvac_parser_state p_state; + uint8_t p_tmo; + uint8_t p_type; + uint8_t p_sum; + uint8_t p_len; + uint8_t p_off; + uint8_t p_data[MIEL_HVAC_DATABUFLEN]; }; -struct miel_hvac_softc { - TasmotaSerial *sc_serial; - struct miel_hvac_parser sc_parser; +struct miel_hvac_softc +{ + TasmotaSerial *sc_serial; + struct miel_hvac_parser sc_parser; - unsigned int sc_device; - unsigned int sc_tick; - bool sc_settings_set; - bool sc_connected; + unsigned int sc_device; + unsigned int sc_tick; + bool sc_settings_set; + bool sc_connected; - struct miel_hvac_data sc_settings; - struct miel_hvac_data sc_temp; - struct miel_hvac_data sc_status; - struct miel_hvac_data sc_stage; + struct miel_hvac_data sc_settings; + struct miel_hvac_data sc_roomtemp; + struct miel_hvac_data sc_timers; + struct miel_hvac_data sc_status; + struct miel_hvac_data sc_stage; - struct miel_hvac_msg_update - sc_update; - struct miel_hvac_msg_remotetemp - sc_remotetemp; + struct miel_hvac_msg_update_settings sc_settings_update; + struct miel_hvac_msg_update_remotetemp sc_remotetemp_update; }; static inline bool -miel_hvac_update_pending(struct miel_hvac_softc *sc) +miel_hvac_update_settings_pending(struct miel_hvac_softc *sc) { - struct miel_hvac_msg_update *update = &sc->sc_update; - + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; return (update->flags != htons(0)); } -static struct miel_hvac_softc *miel_hvac_sc = nullptr; +static struct miel_hvac_softc *miel_hvac_sc = nullptr; -static void miel_hvac_input_connected(struct miel_hvac_softc *, - const void *, size_t); -static void miel_hvac_input_data(struct miel_hvac_softc *, - const void *, size_t); -static void miel_hvac_input_updated(struct miel_hvac_softc *, - const void *, size_t); +static void miel_hvac_input_connected(struct miel_hvac_softc *, const void *, size_t); +static void miel_hvac_input_data(struct miel_hvac_softc *, const void *, size_t); +static void miel_hvac_input_updated(struct miel_hvac_softc *, const void *, size_t); static enum miel_hvac_parser_state miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) @@ -476,7 +556,8 @@ miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) struct miel_hvac_parser *p = &sc->sc_parser; enum miel_hvac_parser_state nstate = p->p_state; - switch (p->p_state) { + switch (p->p_state) + { case MIEL_HVAC_P_START: if (byte != MIEL_HVAC_H_START) return (MIEL_HVAC_P_START); @@ -484,84 +565,74 @@ miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) /* reset state */ p->p_sum = 0; p->p_tmo = 0; - nstate = MIEL_HVAC_P_TYPE; break; - case MIEL_HVAC_P_TYPE: p->p_type = byte; nstate = MIEL_HVAC_P_MIDDLE1; break; - case MIEL_HVAC_P_MIDDLE1: - if (byte != MIEL_HVAC_H_MIDDLE1) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": parse state MIDDLE1 expected %02x got %02x" - ", restarting"), MIEL_HVAC_H_MIDDLE1, byte); + if (byte != MIEL_HVAC_H_MIDDLE1) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": parse state MIDDLE1 expected %02x got %02x" + ", restarting"), + MIEL_HVAC_H_MIDDLE1, byte); return (MIEL_HVAC_P_START); } - nstate = MIEL_HVAC_P_MIDDLE2; break; - case MIEL_HVAC_P_MIDDLE2: - if (byte != MIEL_HVAC_H_MIDDLE2) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": parse state MIDDLE2 expected %02x got %02x" - ", restarting"), MIEL_HVAC_H_MIDDLE2, byte); + if (byte != MIEL_HVAC_H_MIDDLE2) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": parse state MIDDLE2 expected %02x got %02x" + ", restarting"), + MIEL_HVAC_H_MIDDLE2, byte); return (MIEL_HVAC_P_START); } - nstate = MIEL_HVAC_P_LEN; break; - case MIEL_HVAC_P_LEN: - if (byte == 0) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": skipping 0 byte message type 0x%02x"), - p->p_type); + if (byte == 0) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": skipping 0 byte message type 0x%02x"), p->p_type); return (MIEL_HVAC_P_SKIP_CKSUM); } - p->p_len = byte; p->p_off = 0; - switch (p->p_type) { + switch (p->p_type) + { case MIEL_HVAC_H_TYPE_CONNECTED: case MIEL_HVAC_H_TYPE_DATA: case MIEL_HVAC_H_TYPE_UPDATED: break; default: - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": skipping unknown message type 0x%02x"), - p->p_type); + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": skipping unknown message type 0x%02x"), p->p_type); return (MIEL_HVAC_P_SKIP); } - if (byte > sizeof(p->p_data)) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": skipping %u data bytes of message type 0x%02x"), - p->p_len, p->p_type); + if (byte > sizeof(p->p_data)) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": skipping %u data bytes of message type 0x%02x"), p->p_len, p->p_type); return (MIEL_HVAC_P_SKIP); } - nstate = MIEL_HVAC_P_DATA; break; - case MIEL_HVAC_P_DATA: p->p_data[p->p_off++] = byte; if (p->p_off >= p->p_len) nstate = MIEL_HVAC_P_CKSUM; - break; + break; case MIEL_HVAC_P_CKSUM: - if (miel_hvac_cksum_fini(p->p_sum) != byte) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": checksum failed, restarting")); + if (miel_hvac_cksum_fini(p->p_sum) != byte) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": checksum failed, restarting")); return (MIEL_HVAC_P_START); } - switch (p->p_type) { + switch (p->p_type) + { case MIEL_HVAC_H_TYPE_CONNECTED: miel_hvac_input_connected(sc, p->p_data, p->p_len); break; @@ -575,7 +646,6 @@ miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) /* this message is done, wait for another */ return (MIEL_HVAC_P_START); - case MIEL_HVAC_P_SKIP: if (++p->p_off >= p->p_len) return (MIEL_HVAC_P_SKIP_CKSUM); @@ -583,7 +653,6 @@ miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) case MIEL_HVAC_P_SKIP_CKSUM: return (MIEL_HVAC_P_START); } - p->p_sum += byte; return (nstate); @@ -596,7 +665,8 @@ miel_hvac_write(struct miel_hvac_softc *sc, const uint8_t *bytes, size_t len) uint8_t cksum = 0; size_t i; - for (i = 0; i < len; i++) { + for (i = 0; i < len; i++) + { uint8_t b = bytes[i]; serial->write(b); cksum += b; @@ -606,8 +676,7 @@ miel_hvac_write(struct miel_hvac_softc *sc, const uint8_t *bytes, size_t len) } static void -miel_hvac_send(struct miel_hvac_softc *sc, uint8_t type, - const void *data, size_t len) +miel_hvac_send(struct miel_hvac_softc *sc, uint8_t type, const void *data, size_t len) { TasmotaSerial *serial = sc->sc_serial; struct miel_hvac_header h = { @@ -624,28 +693,24 @@ miel_hvac_send(struct miel_hvac_softc *sc, uint8_t type, char hex_h[(sizeof(h) + 1) * 2]; char hex_d[(len + 1) * 2]; - AddLog(LOG_LEVEL_DEBUG, - PSTR(MIEL_HVAC_LOGNAME ": sending %s %s %02x"), - ToHex_P((uint8_t *)&h, sizeof(h), hex_h, sizeof(hex_h)), - ToHex_P((uint8_t *)data, len, hex_d, sizeof(hex_d)), - miel_hvac_cksum_fini(cksum)); + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": sending %s %s %02x"), ToHex_P((uint8_t *)&h, sizeof(h), hex_h, sizeof(hex_h)), ToHex_P((uint8_t *)data, len, hex_d, sizeof(hex_d)), miel_hvac_cksum_fini(cksum)); serial->write(miel_hvac_cksum_fini(cksum)); serial->flush(); } -#define miel_hvac_send_connect(_sc) \ - miel_hvac_send((_sc), MIEL_HVAC_H_TYPE_CONNECT, \ - miel_hvac_msg_connect, sizeof(miel_hvac_msg_connect)) +#define miel_hvac_send_connect(_sc) \ + miel_hvac_send((_sc), MIEL_HVAC_H_TYPE_CONNECT, \ + miel_hvac_msg_connect, sizeof(miel_hvac_msg_connect)) static const struct miel_hvac_map * -miel_hvac_map_byname(const char *name, - const struct miel_hvac_map *m, size_t n) +miel_hvac_map_byname(const char *name, const struct miel_hvac_map *m, size_t n) { const struct miel_hvac_map *e; size_t i; - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) + { e = &m[i]; if (strcasecmp(e->name, name) == 0) return (e); @@ -655,13 +720,13 @@ miel_hvac_map_byname(const char *name, } static const char * -miel_hvac_map_byval(uint8_t byte, - const struct miel_hvac_map *m, size_t n) +miel_hvac_map_byval(uint8_t byte, const struct miel_hvac_map *m, size_t n) { const struct miel_hvac_map *e; size_t i; - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) + { e = &m[i]; if (byte == e->byte) return (e->name); @@ -673,46 +738,40 @@ miel_hvac_map_byval(uint8_t byte, static void miel_hvac_request(struct miel_hvac_softc *sc, uint8_t type) { - struct miel_hvac_msg_request request = { type }; - - miel_hvac_send(sc, MIEL_HVAC_H_TYPE_REQUEST, - &request, sizeof(request)); + struct miel_hvac_msg_request request = {type}; + miel_hvac_send(sc, MIEL_HVAC_H_TYPE_REQUEST, &request, sizeof(request)); } static void -miel_hvac_init_update(struct miel_hvac_msg_update *update) +miel_hvac_init_update_settings(struct miel_hvac_msg_update_settings *update) { memset(update, 0, sizeof(*update)); update->one = 1; } static inline void -miel_hvac_send_update(struct miel_hvac_softc *sc, - const struct miel_hvac_msg_update *update) +miel_hvac_send_update_settings(struct miel_hvac_softc *sc, const struct miel_hvac_msg_update_settings *update) { miel_hvac_send(sc, MIEL_HVAC_H_TYPE_UPDATE, update, sizeof(*update)); } static inline void -miel_hvac_send_remotetemp(struct miel_hvac_softc *sc, - const struct miel_hvac_msg_remotetemp *remotetemp) +miel_hvac_send_update_remotetemp(struct miel_hvac_softc *sc, const struct miel_hvac_msg_update_remotetemp *update) { - miel_hvac_send(sc, MIEL_HVAC_H_TYPE_UPDATE, - remotetemp, sizeof(*remotetemp)); + miel_hvac_send(sc, MIEL_HVAC_H_TYPE_UPDATE, update, sizeof(*update)); } static bool miel_hvac_set_power(struct miel_hvac_softc *sc) { - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; uint16_t source = XdrvMailbox.payload; if (source == SRC_SWITCH) return (false); - update->flags |= htons(MIEL_HVAC_UPDATE_F_POWER); - update->power = (XdrvMailbox.index & (1 << sc->sc_device)) ? - MIEL_HVAC_UPDATE_POWER_ON : MIEL_HVAC_UPDATE_POWER_OFF; + update->flags |= htons(MIEL_HVAC_SETTINGS_F_POWER); + update->power = (XdrvMailbox.index & (1 << sc->sc_device)) ? MIEL_HVAC_SETTINGS_POWER_ON : MIEL_HVAC_SETTINGS_POWER_OFF; return (true); } @@ -727,20 +786,19 @@ static void miel_hvac_cmnd_setfanspeed(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_fan_map, nitems(miel_hvac_fan_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_fan_map, nitems(miel_hvac_fan_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_FAN); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_FAN); update->fan = e->byte; ResponseCmndChar_P(e->name); @@ -750,20 +808,19 @@ static void miel_hvac_cmnd_setmode(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_mode_map, nitems(miel_hvac_mode_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_mode_map, nitems(miel_hvac_mode_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_MODE); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_MODE); update->mode = e->byte; ResponseCmndChar_P(e->name); @@ -773,15 +830,16 @@ static void miel_hvac_cmnd_sethamode(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - if (strcasecmp(XdrvMailbox.data, "off") == 0) { - update->flags |= htons(MIEL_HVAC_UPDATE_F_POWER); - update->power = MIEL_HVAC_UPDATE_POWER_OFF; + if (strcasecmp(XdrvMailbox.data, "off") == 0) + { + update->flags |= htons(MIEL_HVAC_SETTINGS_F_POWER); + update->power = MIEL_HVAC_SETTINGS_POWER_OFF; ResponseCmndChar_P(PSTR("off")); return; } @@ -791,16 +849,14 @@ miel_hvac_cmnd_sethamode(void) * but that would mean power gets turned on even if there's * an invalid argument. */ - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_mode_map, nitems(miel_hvac_mode_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_mode_map, nitems(miel_hvac_mode_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_POWER) | - htons(MIEL_HVAC_UPDATE_F_MODE); - update->power = MIEL_HVAC_UPDATE_POWER_ON; + update->flags |= htons(MIEL_HVAC_SETTINGS_F_POWER) | htons(MIEL_HVAC_SETTINGS_F_MODE); + update->power = MIEL_HVAC_SETTINGS_POWER_ON; update->mode = e->byte; ResponseCmndChar_P(e->name); @@ -810,25 +866,27 @@ static void miel_hvac_cmnd_settemp(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; float degc; if (XdrvMailbox.data_len == 0) return; degc = strtof(XdrvMailbox.data, nullptr); - if (degc < MIEL_HVAC_UPDATE_TEMP_MIN || - degc > MIEL_HVAC_UPDATE_TEMP_MAX) { + if (degc < MIEL_HVAC_SETTINGS_TEMP_MIN || degc > MIEL_HVAC_SETTINGS_TEMP_MAX) + { miel_hvac_respond_unsupported(); return; } - update->flags |= htons(MIEL_HVAC_UPDATE_F_TEMP); - if (!temp_type) { + update->flags |= htons(MIEL_HVAC_SETTINGS_F_TEMP); + if (!temp_type) + { update->temp = miel_hvac_deg2temp(degc); update->temp05 = 0; } - else { + else + { update->temp = 0; update->temp05 = miel_hvac_deg2temp(degc); } @@ -840,20 +898,19 @@ static void miel_hvac_cmnd_setvane(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_vane_map, nitems(miel_hvac_vane_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_vane_map, nitems(miel_hvac_vane_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_VANE); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_VANE); update->vane = e->byte; ResponseCmndChar_P(e->name); @@ -863,20 +920,19 @@ static void miel_hvac_cmnd_setprohibit(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_PROHIBIT); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_PROHIBIT); update->prohibit = e->byte; ResponseCmndChar_P(e->name); @@ -886,20 +942,19 @@ static void miel_hvac_cmnd_setwidevane(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_WIDEVANE); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_WIDEVANE); update->widevane = e->byte; ResponseCmndChar_P(e->name); @@ -909,20 +964,19 @@ static void miel_hvac_cmnd_setairdirection(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_AIRDIRECTION); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_AIRDIRECTION); update->airdirection = e->byte; ResponseCmndChar_P(e->name); @@ -944,24 +998,22 @@ miel_hvac_remotetemp_degc2old(long degc) else if (degc > MIEL_HVAC_REMOTETEMP_OLD_MAX) degc = MIEL_HVAC_REMOTETEMP_OLD_MIN; - return ((degc - MIEL_HVAC_REMOTETEMP_OLD_MIN) * - MIEL_HVAC_REMOTETEMP_OLD_FACTOR); + return ((degc - MIEL_HVAC_REMOTETEMP_OLD_MIN) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR); } static void -miel_hvac_remotetemp_auto_clear(void) +miel_hvac_remotetemp_auto_clear(void) { - struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_remotetemp *rt = &sc->sc_remotetemp; + struct miel_hvac_softc *sc = miel_hvac_sc; + struct miel_hvac_msg_update_remotetemp *update = &sc->sc_remotetemp_update; uint8_t control = MIEL_HVAC_REMOTETEMP_CLR; long degc = 0; - memset(rt, 0, sizeof(*rt)); - rt->seven = 0x7; - rt->control = control; - rt->temp_old = miel_hvac_remotetemp_degc2old(degc); - rt->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; - + memset(update, 0, sizeof(*update)); + update->seven = 0x7; + update->control = control; + update->temp_old = miel_hvac_remotetemp_degc2old(degc); + update->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; remotetemp_clear = false; } @@ -972,7 +1024,8 @@ miel_hvac_cmnd_remotetemp_auto_clear_time(void) return; unsigned long clear_time = strtoul(XdrvMailbox.data, nullptr, 10); - if (clear_time < 1000 || clear_time > 600000) { + if (clear_time < 1000 || clear_time > 600000) + { miel_hvac_respond_unsupported(); return; } @@ -985,20 +1038,22 @@ static void miel_hvac_cmnd_remotetemp(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_remotetemp *rt = &sc->sc_remotetemp; + struct miel_hvac_msg_update_remotetemp *update = &sc->sc_remotetemp_update; uint8_t control = MIEL_HVAC_REMOTETEMP_SET; long degc; if (XdrvMailbox.data_len == 0) return; - if (strcasecmp(XdrvMailbox.data, "clear") == 0) { + if (strcasecmp(XdrvMailbox.data, "clear") == 0) + { control = MIEL_HVAC_REMOTETEMP_CLR; degc = 0; ResponseCmndChar_P("clear"); - remotetemp_last_call_time = 0; - } else { + } + else + { degc = strtol(XdrvMailbox.data, nullptr, 0); /* clamp the argument to supported values */ @@ -1008,12 +1063,10 @@ miel_hvac_cmnd_remotetemp(void) degc = MIEL_HVAC_REMOTETEMP_MAX; ResponseCmndNumber(degc); - remotetemp_last_call_time = millis(); } - - memset(rt, 0, sizeof(*rt)); - rt->seven = 0x7; - rt->control = control; + memset(update, 0, sizeof(*update)); + update->seven = 0x7; + update->control = control; /* * Different HVACs (or more likely different generations @@ -1022,11 +1075,11 @@ miel_hvac_cmnd_remotetemp(void) * support all known types of HVACs. */ - rt->temp_old = miel_hvac_remotetemp_degc2old(degc); - rt->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * - MIEL_HVAC_REMOTETEMP_OLD_FACTOR; + update->temp_old = miel_hvac_remotetemp_degc2old(degc); + update->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; - remotetemp_clear = control == MIEL_HVAC_REMOTETEMP_SET ? true : false; + remotetemp_last_call_time = control == MIEL_HVAC_REMOTETEMP_SET ? millis() : 0; + remotetemp_clear = control == MIEL_HVAC_REMOTETEMP_SET ? true : false; } #ifdef MIEL_HVAC_DEBUG @@ -1050,116 +1103,97 @@ miel_hvac_cmnd_request(void) */ static void -miel_hvac_log_bytes(struct miel_hvac_softc *sc, const char *name, - const void *buf, size_t len) +miel_hvac_log_bytes(struct miel_hvac_softc *sc, const char *name, const void *buf, size_t len) { char hex[(MIEL_HVAC_DATABUFLEN + 1) * 2]; const unsigned char *b = (const unsigned char *)buf; - - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": response %s %s"), name, ToHex_P(b, len, hex, sizeof(hex))); + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": response %s %s"), name, ToHex_P(b, len, hex, sizeof(hex))); } static void -miel_hvac_input_connected(struct miel_hvac_softc *sc, - const void *buf, size_t len) +miel_hvac_input_connected(struct miel_hvac_softc *sc, const void *buf, size_t len) { - AddLog(LOG_LEVEL_INFO, - PSTR(MIEL_HVAC_LOGNAME ": connected to Mitsubishi Electric HVAC")); + AddLog(LOG_LEVEL_INFO, PSTR(MIEL_HVAC_LOGNAME ": connected to Mitsubishi Electric HVAC")); sc->sc_connected = 1; } static void miel_hvac_publish_settings(struct miel_hvac_softc *sc) { - const struct miel_hvac_data_settings *set = - &sc->sc_settings.data.settings; + const struct miel_hvac_data_settings *set = &sc->sc_settings.data.settings; char hex[(sizeof(sc->sc_settings) + 1) * 2]; char temp[33]; const char *name; const char *name_swing_h; - name = miel_hvac_map_byval(set->power, - miel_hvac_power_map, nitems(miel_hvac_power_map)); - if (name != NULL) { - Response_P(PSTR("{\"" D_JSON_IRHVAC_POWER "\":\"%s\""), - name); - } + name = miel_hvac_map_byval(set->power, miel_hvac_power_map, nitems(miel_hvac_power_map)); + if (name != NULL) + { + Response_P(PSTR("{\"" D_JSON_IRHVAC_POWER "\":\"%s\""), name); + } - name = miel_hvac_map_byval( set->mode & - MIEL_HVAC_SETTINGS_MODE_MASK, - miel_hvac_mode_map, nitems(miel_hvac_mode_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_MODE "\":\"%s\""), - name); - ResponseAppend_P(PSTR(",\"HA" D_JSON_IRHVAC_MODE "\":\"%s\""), - set->power ? name : "off"); + name = miel_hvac_map_byval(set->mode & MIEL_HVAC_SETTINGS_MODE_MASK, miel_hvac_mode_map, nitems(miel_hvac_mode_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_MODE "\":\"%s\""), name); + ResponseAppend_P(PSTR(",\"HA" D_JSON_IRHVAC_MODE "\":\"%s\""), set->power ? name : "off"); } - if (set->temp05 == 0) { - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), - Settings->flag2.temperature_resolution, temp); + if (set->temp05 == 0) + { + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), Settings->flag2.temperature_resolution, temp); } - else { + else + { temp_type = true; - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), - Settings->flag2.temperature_resolution, temp); + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), Settings->flag2.temperature_resolution, temp); } ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_TEMP "\":%s"), temp); - name = miel_hvac_map_byval(set->fan, - miel_hvac_fan_map, nitems(miel_hvac_fan_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_FANSPEED "\":\"%s\""), - name); + name = miel_hvac_map_byval(set->fan, miel_hvac_fan_map, nitems(miel_hvac_fan_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_FANSPEED "\":\"%s\""), name); } - name = miel_hvac_map_byval(set->vane, - miel_hvac_vane_map, nitems(miel_hvac_vane_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_SWINGV "\":\"%s\""), - name); + name = miel_hvac_map_byval(set->vane, miel_hvac_vane_map, nitems(miel_hvac_vane_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_SWINGV "\":\"%s\""), name); } - name_swing_h = miel_hvac_map_byval(set->widevane & - MIEL_HVAC_SETTTINGS_WIDEVANE_MASK, - miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); - if (name_swing_h != NULL) { - ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_SWINGH "\":\"%s\""), - name_swing_h); + name_swing_h = miel_hvac_map_byval(set->widevane & MIEL_HVAC_SETTINGS_WIDEVANE_MASK, miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); + if (name_swing_h != NULL) + { + ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_SWINGH "\":\"%s\""), name_swing_h); } - name = miel_hvac_map_byval(set->airdirection, - miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"AirDirection\":\"%s\""), - name_swing_h == "auto" ? name : "OFF"); + name = miel_hvac_map_byval(set->airdirection, miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"AirDirection\":\"%s\""), name_swing_h == "auto" ? name : "OFF"); } - name = miel_hvac_map_byval(set->prohibit, - miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"Prohibit\":\"%s\""), - name); + name = miel_hvac_map_byval(set->prohibit, miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"Prohibit\":\"%s\""), name); } - ResponseAppend_P(PSTR(",\"Bytes\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_settings, sizeof(sc->sc_settings), - hex, sizeof(hex))); - + ResponseAppend_P(PSTR(",\"Settings\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_settings, sizeof(sc->sc_settings), hex, sizeof(hex))); ResponseAppend_P(PSTR("}")); MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR("HVACSettings")); } static void -miel_hvac_input_settings(struct miel_hvac_softc *sc, - const struct miel_hvac_data *d) +miel_hvac_input_settings(struct miel_hvac_softc *sc, const struct miel_hvac_data *d) { const struct miel_hvac_data_settings *set = &d->data.settings; uint32_t state = set->power ? 1 : 0; /* see ExecuteCommandPower */ bool publish; - if (miel_hvac_update_pending(sc)) { + if (miel_hvac_update_settings_pending(sc)) + { /* * Don't flop around printing settings that we might be * changing, but also force them to be published again. @@ -1171,8 +1205,7 @@ miel_hvac_input_settings(struct miel_hvac_softc *sc, if (bitRead(TasmotaGlobal.power, sc->sc_device) != !!state) ExecuteCommandPower(sc->sc_device, state, SRC_SWITCH); - publish = (sc->sc_settings_set == 0) || - (memcmp(d, &sc->sc_settings, sizeof(sc->sc_settings)) != 0); + publish = (sc->sc_settings_set == 0) || (memcmp(d, &sc->sc_settings, sizeof(sc->sc_settings)) != 0); sc->sc_settings_set = 1; sc->sc_settings = *d; @@ -1181,52 +1214,47 @@ miel_hvac_input_settings(struct miel_hvac_softc *sc, } static void -miel_hvac_data_response(struct miel_hvac_softc *sc, - const struct miel_hvac_data *d) +miel_hvac_data_response(struct miel_hvac_softc *sc, const struct miel_hvac_data *d) { char hex[(sizeof(*d) + 1) * 2]; - - Response_P(PSTR("{\"Bytes\":\"%s\"}"), - ToHex_P((uint8_t *)d, sizeof(*d), hex, sizeof(hex))); - + Response_P(PSTR("{\"Bytes\":\"%s\"}"), ToHex_P((uint8_t *)d, sizeof(*d), hex, sizeof(hex))); MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR("HVACData")); } static void -miel_hvac_input_sensor(struct miel_hvac_softc *sc, struct miel_hvac_data *dst, - const struct miel_hvac_data *src) +miel_hvac_input_sensor(struct miel_hvac_softc *sc, struct miel_hvac_data *dst, const struct miel_hvac_data *src) { bool publish; - publish = (memcmp(dst, src, sizeof(*dst)) != 0); *dst = *src; if (publish) MqttPublishSensor(); - } static void -miel_hvac_input_data(struct miel_hvac_softc *sc, - const void *buf, size_t len) +miel_hvac_input_data(struct miel_hvac_softc *sc, const void *buf, size_t len) { const struct miel_hvac_data *d; miel_hvac_log_bytes(sc, "data", buf, len); - if (len < sizeof(*d)) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": short data response (%zu < %zu)"), len, sizeof(*d)); + if (len < sizeof(*d)) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": short data response (%zu < %zu)"), len, sizeof(*d)); return; } - d = (const struct miel_hvac_data *)buf; - switch (d->type) { + switch (d->type) + { case MIEL_HVAC_DATA_T_SETTINGS: miel_hvac_input_settings(sc, d); break; case MIEL_HVAC_DATA_T_ROOMTEMP: - miel_hvac_input_sensor(sc, &sc->sc_temp, d); + miel_hvac_input_sensor(sc, &sc->sc_roomtemp, d); + break; + case MIEL_HVAC_DATA_T_TIMERS: + miel_hvac_input_sensor(sc, &sc->sc_timers, d); break; case MIEL_HVAC_DATA_T_STATUS: miel_hvac_input_sensor(sc, &sc->sc_status, d); @@ -1241,8 +1269,7 @@ miel_hvac_input_data(struct miel_hvac_softc *sc, } static void -miel_hvac_input_updated(struct miel_hvac_softc *sc, - const void *buf, size_t len) +miel_hvac_input_updated(struct miel_hvac_softc *sc, const void *buf, size_t len) { miel_hvac_log_bytes(sc, "updated", buf, len); } @@ -1261,35 +1288,36 @@ miel_hvac_pre_init(void) return; sc = (struct miel_hvac_softc *)malloc(sizeof(*sc)); - if (sc == NULL) { - AddLog(LOG_LEVEL_ERROR, - PSTR(MIEL_HVAC_LOGNAME ": unable to allocate state")); + if (sc == NULL) + { + AddLog(LOG_LEVEL_ERROR, PSTR(MIEL_HVAC_LOGNAME ": unable to allocate state")); return; } memset(sc, 0, sizeof(*sc)); - miel_hvac_init_update(&sc->sc_update); + miel_hvac_init_update_settings(&sc->sc_settings_update); - sc->sc_serial = new TasmotaSerial(Pin(GPIO_MIEL_HVAC_RX), - Pin(GPIO_MIEL_HVAC_TX), 2); - - if (!sc->sc_serial->begin(baudrate, SERIAL_8E1)) { + sc->sc_serial = new TasmotaSerial(Pin(GPIO_MIEL_HVAC_RX), Pin(GPIO_MIEL_HVAC_TX), 2); + if (!sc->sc_serial->begin(baudrate, SERIAL_8E1)) + { AddLog(LOG_LEVEL_ERROR, - PSTR(MIEL_HVAC_LOGNAME ": unable to begin serial " - "(baudrate %d)"), baudrate); + PSTR(MIEL_HVAC_LOGNAME ": unable to begin serial " + "(baudrate %d)"), + baudrate); goto del; } - if (sc->sc_serial->hardwareSerial()) { + if (sc->sc_serial->hardwareSerial()) + { ClaimSerial(); SetSerial(baudrate, TS_SERIAL_8E1); } #ifdef ESP32 - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": Serial UART%d"), sc->sc_serial->getUart()); + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": Serial UART%d"), sc->sc_serial->getUart()); #endif sc->sc_device = TasmotaGlobal.devices_present; - UpdateDevicesPresent(1); /* claim a POWER device slot */ + UpdateDevicesPresent(1); /* claim a POWER device slot */ miel_hvac_sc = sc; return; @@ -1304,9 +1332,9 @@ miel_hvac_loop(struct miel_hvac_softc *sc) { TasmotaSerial *serial = sc->sc_serial; - while (serial->available()) { + while (serial->available()) + { yield(); - sc->sc_parser.p_state = miel_hvac_parse(sc, serial->read()); } } @@ -1314,163 +1342,199 @@ miel_hvac_loop(struct miel_hvac_softc *sc) static void miel_hvac_sensor(struct miel_hvac_softc *sc) { - const struct miel_hvac_data_settings *set = - &sc->sc_settings.data.settings; - char hex[(sizeof(sc->sc_settings) + 1) * 2]; - char temp[33]; const char *name; + const char *mode; const char *name_swing_h; - ResponseAppend_P(PSTR("," "\"MiElHVAC\":{")); + ResponseAppend_P(PSTR(",\"MiElHVAC\":{")); - name = miel_hvac_map_byval(set->power, - miel_hvac_power_map, nitems(miel_hvac_power_map)); - if (name != NULL) { - ResponseAppend_P(PSTR("\"Power\":\"%s\""), - name); + if (sc->sc_settings.type != 0) + { + const struct miel_hvac_data_settings *set = &sc->sc_settings.data.settings; + char hex[(sizeof(sc->sc_settings) + 1) * 2]; + char temp[33]; + + name = miel_hvac_map_byval(set->power, miel_hvac_power_map, nitems(miel_hvac_power_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR("\"Power\":\"%s\""), name); + } + + mode = miel_hvac_map_byval(set->mode & MIEL_HVAC_SETTINGS_MODE_MASK, miel_hvac_mode_map, nitems(miel_hvac_mode_map)); + if (mode != NULL) + { + ResponseAppend_P(PSTR(",\"Mode\":\"%s\""), mode); + } + + if (set->temp05 == 0) + { + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), Settings->flag2.temperature_resolution, temp); + } + else + { + temp_type = true; + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), Settings->flag2.temperature_resolution, temp); + } + ResponseAppend_P(PSTR(",\"SetTemperature\":\"%s\""), temp); + + name = miel_hvac_map_byval(set->fan, miel_hvac_fan_map, nitems(miel_hvac_fan_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"FanSpeed\":\"%s\""), name); + } + + name = miel_hvac_map_byval(set->vane, miel_hvac_vane_map, nitems(miel_hvac_vane_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"SwingV\":\"%s\""), name); + } + + name_swing_h = miel_hvac_map_byval(set->widevane & MIEL_HVAC_SETTINGS_WIDEVANE_MASK, miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); + if (name_swing_h != NULL) + { + ResponseAppend_P(PSTR(",\"SwingH\":\"%s\""), name_swing_h); + } + + name = miel_hvac_map_byval(set->airdirection, miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"AirDirection\":\"%s\""), name_swing_h == "auto" ? name : "off"); + } + + name = miel_hvac_map_byval(set->prohibit, miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"Prohibit\":\"%s\""), name); + } + + ResponseAppend_P(PSTR(",\"Settings\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_settings, sizeof(sc->sc_settings), hex, sizeof(hex))); } - name = miel_hvac_map_byval( set->mode & - MIEL_HVAC_SETTINGS_MODE_MASK, - miel_hvac_mode_map, nitems(miel_hvac_mode_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"Mode\":\"%s\""), - name); - } - if (set->temp05 == 0) { - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), - Settings->flag2.temperature_resolution, temp); - } - else { - temp_type = true; - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), - Settings->flag2.temperature_resolution, temp); - } - ResponseAppend_P(PSTR(",\"SetTemperature\":\"%s\""), temp); - - name = miel_hvac_map_byval(set->fan, - miel_hvac_fan_map, nitems(miel_hvac_fan_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"FanSpeed\":\"%s\""), - name); - } - - name = miel_hvac_map_byval(set->vane, - miel_hvac_vane_map, nitems(miel_hvac_vane_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"SwingV\":\"%s\""), - name); - } - - name_swing_h = miel_hvac_map_byval(set->widevane & - MIEL_HVAC_SETTTINGS_WIDEVANE_MASK, - miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); - if (name_swing_h != NULL) { - ResponseAppend_P(PSTR(",\"SwingH\":\"%s\""), - name_swing_h); - } - - name = miel_hvac_map_byval(set->airdirection, - miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"AirDirection\":\"%s\""), - name_swing_h == "auto" ? name : "off"); - } - - name = miel_hvac_map_byval(set->prohibit, - miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"Prohibit\":\"%s\""), - name); - } - - ResponseAppend_P(PSTR(",\"Bytes\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_settings, sizeof(sc->sc_settings), - hex, sizeof(hex))); - - if (sc->sc_temp.type != 0) { - const struct miel_hvac_data_roomtemp *rt = - &sc->sc_temp.data.roomtemp; + if (sc->sc_roomtemp.type != 0) + { + const struct miel_hvac_data_roomtemp *rt = &sc->sc_roomtemp.data.roomtemp; + char hex[(sizeof(sc->sc_roomtemp) + 1) * 2]; char room_temp[33]; - if(rt->temp05 == 0) { + if (rt->temp05 == 0) + { unsigned int temp = miel_hvac_roomtemp2deg(rt->temp); - dtostrfd(ConvertTemp(temp), - Settings->flag2.temperature_resolution, room_temp); - } - else { + dtostrfd(ConvertTemp(temp), Settings->flag2.temperature_resolution, room_temp); + } + else + { temp_type = true; float temp = miel_hvac_roomtemp2deg(rt->temp05); - dtostrfd(ConvertTemp(temp), - Settings->flag2.temperature_resolution, room_temp); + dtostrfd(ConvertTemp(temp), Settings->flag2.temperature_resolution, room_temp); } - ResponseAppend_P(PSTR(",\"Temperature\":\"%s\""), - room_temp); + ResponseAppend_P(PSTR(",\"Temperature\":\"%s\""), room_temp); + ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorState\":\"%s\""), remotetemp_clear ? "on" : "off"); - ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorState\":\"%s\""), - remotetemp_clear ? "ON" : "OFF"); + char remotetempautocleartime[33]; + ultoa(remotetemp_auto_clear_time, remotetempautocleartime, 10); + ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorAutoClearTime\":\"%s\""), remotetempautocleartime); - char remotetempautocleartime[33]; - ultoa(remotetemp_auto_clear_time, remotetempautocleartime, 10); - ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorAutoClearTime\":\"%s\""), - remotetempautocleartime); - - if(rt->outdoortemp > 1) { - char outdoor_temp[33]; - float temp = miel_hvac_outdoortemp2deg(rt->outdoortemp); - dtostrfd(ConvertTemp(temp), 1, outdoor_temp); - ResponseAppend_P(PSTR(",\"OutdoorTemperature\":\"%s\""), - outdoor_temp); + if (rt->outdoortemp > 1) + { + char outdoor_temp[33]; + float temp = miel_hvac_outdoortemp2deg(rt->outdoortemp); + dtostrfd(ConvertTemp(temp), 1, outdoor_temp); + ResponseAppend_P(PSTR(",\"OutdoorTemperature\":\"%s\""), outdoor_temp); } uint32_t combined_time = ((uint32_t)rt->operationtime << 16) | ((uint32_t)rt->operationtime1 << 8) | (uint32_t)rt->operationtime2; float operationtime_in_min = (float)combined_time; - char operationtime[33]; - dtostrf(operationtime_in_min, 1, 0, operationtime); - ResponseAppend_P(PSTR(",\"OperationTime\":\"%s\""), - operationtime); + char operationtime[33]; + dtostrf(operationtime_in_min, 1, 0, operationtime); + ResponseAppend_P(PSTR(",\"OperationTime\":\"%s\""), operationtime); - ResponseAppend_P(PSTR(",\"RoomTemp\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_temp, sizeof(sc->sc_temp), - hex, sizeof(hex))); + ResponseAppend_P(PSTR(",\"RoomTemp\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_roomtemp, sizeof(sc->sc_roomtemp), hex, sizeof(hex))); } - if (sc->sc_status.type != 0) { - const struct miel_hvac_data_status *status = - &sc->sc_status.data.status; + if (sc->sc_timers.type != 0) + { + const struct miel_hvac_data_timers *timer = &sc->sc_timers.data.timers; + char hex[(sizeof(sc->sc_timers) + 1) * 2]; - name = miel_hvac_map_byval(status->compressor, - miel_hvac_compressor_map, nitems(miel_hvac_compressor_map)); - ResponseAppend_P(PSTR(",\"Compressor\":\"%s\""), - name != NULL ? name : "N/A"); + name = miel_hvac_map_byval(timer->mode, miel_hvac_timer_mode_map, nitems(miel_hvac_timer_mode_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"TimerMode\":\"%s\""), name); + + unsigned int on_timer = timer->onminutes * 10; + char timeron[33]; + utoa(on_timer, timeron, 10); + ResponseAppend_P(PSTR(",\"TimerOn\":\"%s\""), timeron); + + unsigned int timer_on_remaining = timer->onminutesremaining * 10; + char timeronremaining[33]; + utoa(timer_on_remaining, timeronremaining, 10); + ResponseAppend_P(PSTR(",\"TimerOnRemaining\":\"%s\""), timeronremaining); + + unsigned int off_timer = timer->offminutes * 10; + char timeroff[33]; + utoa(off_timer, timeroff, 10); + ResponseAppend_P(PSTR(",\"TimerOff\":\"%s\""), timeroff); + + unsigned int timer_off_remaining = timer->offminutesremaining * 10; + char timeroffremaining[33]; + utoa(timer_off_remaining, timeroffremaining, 10); + ResponseAppend_P(PSTR(",\"TimerOffRemaining\":\"%s\""), timeroffremaining); + } + + ResponseAppend_P(PSTR(",\"Timers\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_timers, sizeof(sc->sc_timers), hex, sizeof(hex))); + } + + if (sc->sc_status.type != 0) + { + const struct miel_hvac_data_status *status = &sc->sc_status.data.status; + char hex[(sizeof(sc->sc_status) + 1) * 2]; + + name = miel_hvac_map_byval(status->compressor, miel_hvac_compressor_map, nitems(miel_hvac_compressor_map)); + ResponseAppend_P(PSTR(",\"Compressor\":\"%s\""), name != NULL ? name : "N/A"); unsigned int compressor_frequency = status->compressorfrequency; - char compressorfrequency[33]; - utoa(compressor_frequency, compressorfrequency, 10); - ResponseAppend_P(PSTR(",\"CompressorFrequency\":\"%s\""), - compressorfrequency); + char compressorfrequency[33]; + utoa(compressor_frequency, compressorfrequency, 10); + ResponseAppend_P(PSTR(",\"CompressorFrequency\":\"%s\""), compressorfrequency); - uint16_t combined_power = ((uint16_t)status->operationpower << 8) | (uint16_t)status->operationpower1; - char operationpower[33]; - dtostrfd((float)combined_power, 0, operationpower); - ResponseAppend_P(PSTR(",\"OperationPower\":\"%s\""), - operationpower); + uint16_t combined_power = ((uint16_t)status->operationpower << 8) | (uint16_t)status->operationpower1; + char operationpower[33]; + dtostrfd((float)combined_power, 0, operationpower); + ResponseAppend_P(PSTR(",\"OperationPower\":\"%s\""), operationpower); uint16_t combined_energy = ((uint16_t)status->operationenergy << 8) | (uint16_t)status->operationenergy1; float operationenergy_in_kWh = (float)combined_energy / 10.0; - char operationenergy[33]; - dtostrfd((float)operationenergy_in_kWh, 1, operationenergy); - ResponseAppend_P(PSTR(",\"OperationEnergy\":\"%s\""), - operationenergy); + char operationenergy[33]; + dtostrfd((float)operationenergy_in_kWh, 1, operationenergy); + ResponseAppend_P(PSTR(",\"OperationEnergy\":\"%s\""), operationenergy); - ResponseAppend_P(PSTR(",\"Status\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_status, sizeof(sc->sc_status), - hex, sizeof(hex))); + ResponseAppend_P(PSTR(",\"Status\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_status, sizeof(sc->sc_status), hex, sizeof(hex))); } - if (sc->sc_stage.type != 0) { - ResponseAppend_P(PSTR(",\"Stage\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_stage, sizeof(sc->sc_stage), - hex, sizeof(hex))); + if (sc->sc_stage.type != 0) + { + const struct miel_hvac_data_stage *stage = &sc->sc_stage.data.stage; + char hex[(sizeof(sc->sc_stage) + 1) * 2]; + + name = miel_hvac_map_byval(stage->prerun, miel_hvac_stage_prerun_map, nitems(miel_hvac_stage_prerun_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"PrerunStage\":\"%s\""), name); + } + + name = miel_hvac_map_byval(stage->fan, miel_hvac_stage_fan_map, nitems(miel_hvac_stage_fan_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"FanStage\":\"%s\""), name); + } + + name = miel_hvac_map_byval(stage->mode, miel_hvac_stage_mode_map, nitems(miel_hvac_stage_mode_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"ModeStage\":\"%s\""), name == "manual" ? mode : name); + } + + ResponseAppend_P(PSTR(",\"Stage\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_stage, sizeof(sc->sc_stage), hex, sizeof(hex))); } ResponseAppend_P(PSTR("}")); @@ -1484,12 +1548,12 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) * and published. Posting new settings preempts queries for information. */ -enum miel_hvac_connect_states { +enum miel_hvac_connect_states +{ MIEL_HVAC_CONNECT_S_2400_MSG, MIEL_HVAC_CONNECT_S_9600, MIEL_HVAC_CONNECT_S_9600_MSG, MIEL_HVAC_CONNECT_S_2400, - MIEL_HVAC_CONNECT_S_COUNT, }; @@ -1501,8 +1565,8 @@ miel_hvac_connect(struct miel_hvac_softc *sc) unsigned int state; state = (sc->sc_tick++ % MIEL_HVAC_CONNECT_S_COUNT); - - switch (state) { + switch (state) + { case MIEL_HVAC_CONNECT_S_2400: baudrate = 2400; break; @@ -1527,7 +1591,8 @@ miel_hvac_tick(struct miel_hvac_softc *sc) MIEL_HVAC_REQUEST_STATUS, MIEL_HVAC_REQUEST_SETTINGS, MIEL_HVAC_REQUEST_ROOMTEMP, - + MIEL_HVAC_REQUEST_SETTINGS, + MIEL_HVAC_REQUEST_TIMERS, MIEL_HVAC_REQUEST_SETTINGS, /* MUZ-GA80VA doesnt respond :( */ MIEL_HVAC_REQUEST_STAGE, @@ -1536,40 +1601,42 @@ miel_hvac_tick(struct miel_hvac_softc *sc) struct miel_hvac_parser *p = &sc->sc_parser; unsigned int i; - if (p->p_state != MIEL_HVAC_P_START) { - if (p->p_tmo) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": read timeout")); + if (p->p_state != MIEL_HVAC_P_START) + { + if (p->p_tmo) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": read timeout")); sc->sc_parser.p_state = MIEL_HVAC_P_START; - } else { + } + else + { p->p_tmo = 1; return; } } - if (miel_hvac_update_pending(sc)) { - struct miel_hvac_msg_update *update = &sc->sc_update; + if (miel_hvac_update_settings_pending(sc)) + { + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; - miel_hvac_send_update(sc, update); - - miel_hvac_init_update(update); + miel_hvac_send_update_settings(sc, update); + miel_hvac_init_update_settings(update); /* refresh settings on next tick */ sc->sc_tick = 0; return; } - if (sc->sc_remotetemp.seven) { - struct miel_hvac_msg_remotetemp *remotetemp = - &sc->sc_remotetemp; + if (sc->sc_remotetemp_update.seven) + { + struct miel_hvac_msg_update_remotetemp *remotetemp = &sc->sc_remotetemp_update; - miel_hvac_send_remotetemp(sc, remotetemp); + miel_hvac_send_update_remotetemp(sc, remotetemp); memset(remotetemp, 0, sizeof(*remotetemp)); return; } i = (sc->sc_tick++ % nitems(updates)); - miel_hvac_request(sc, updates[i]); } @@ -1590,7 +1657,8 @@ static const char miel_hvac_cmnd_names[] PROGMEM = "|" D_CMND_MIEL_HVAC_REMOTETEMP "|" D_CMND_MIEL_HVAC_REMOTETEMP_AUTO_CLEAR_TIME #ifdef MIEL_HVAC_DEBUG - "|" "HVACRequest" + "|" + "HVACRequest" #endif ; @@ -1610,11 +1678,13 @@ static void (*const miel_hvac_cmnds[])(void) PROGMEM = { #endif }; -bool Xdrv44(uint32_t function) { +bool Xdrv44(uint32_t function) +{ bool result = false; struct miel_hvac_softc *sc = miel_hvac_sc; - switch (function) { + switch (function) + { case FUNC_PRE_INIT: miel_hvac_pre_init(); return (false); @@ -1623,31 +1693,29 @@ bool Xdrv44(uint32_t function) { if (sc == NULL) return (false); - switch (function) { + switch (function) + { case FUNC_LOOP: miel_hvac_loop(sc); break; - case FUNC_SET_DEVICE_POWER: result = miel_hvac_set_power(sc); break; - case FUNC_EVERY_250_MSECOND: if (sc->sc_connected) miel_hvac_tick(sc); else miel_hvac_connect(sc); break; - case FUNC_EVERY_50_MSECOND: case FUNC_EVERY_100_MSECOND: case FUNC_EVERY_200_MSECOND: case FUNC_EVERY_SECOND: - if (remotetemp_clear && ((millis() - remotetemp_last_call_time) > remotetemp_auto_clear_time || remotetemp_last_call_time == 0)) { - miel_hvac_remotetemp_auto_clear(); - } + if (remotetemp_clear && ((millis() - remotetemp_last_call_time) > remotetemp_auto_clear_time || remotetemp_last_call_time == 0)) + { + miel_hvac_remotetemp_auto_clear(); + } break; - case FUNC_JSON_APPEND: miel_hvac_sensor(sc); break; @@ -1655,17 +1723,14 @@ bool Xdrv44(uint32_t function) { if (sc->sc_settings_set) miel_hvac_publish_settings(sc); break; - case FUNC_COMMAND: result = DecodeCommand(miel_hvac_cmnd_names, miel_hvac_cmnds); break; - - case FUNC_ACTIVE: - result = true; - break; + case FUNC_ACTIVE: + result = true; + break; } - return (result); } -#endif // USE_MIEL_HVAC +#endif // USE_MIEL_HVAC From 133cca3fd56d087e8cff5fb365869b60a0e74bb7 Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Sun, 3 Nov 2024 17:33:51 +0100 Subject: [PATCH 075/205] [Solax X1] Finetuning (#22421) --- tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino index 29185eab1..57a138f29 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino @@ -116,8 +116,7 @@ struct SOLAXX1_GLOBALDATA { bool AddressAssigned = true; uint8_t SendRetry_count = 20; uint8_t QueryData_count = 0; - uint8_t QueryID_count = 240; - bool Command_QueryID = false;; + bool Command_QueryID = false; bool Command_QueryConfig = false; bool MeterMode = false; float MeterPower = 5000; @@ -450,7 +449,7 @@ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds AddLog(LOG_LEVEL_INFO, PSTR("SX1: Inverter rated bus voltage: %s"),(char*)TempData); solaxX1_global.Command_QueryID = false; } else { - AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: Inverter serial number: %s"),(char*)solaxX1.SerialNumber); + AddLog(LOG_LEVEL_INFO, PSTR("SX1: Inverter serial number: %s"),(char*)solaxX1.SerialNumber); } DEBUG_SENSOR_LOG(PSTR("SX1: received ID data")); return; @@ -548,11 +547,11 @@ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds return; } -// DEBUG_SENSOR_LOG(PSTR("SX1: solaxX1_global.AddressAssigned: %d, solaxX1_global.QueryData_count: %d, solaxX1_global.SendRetry_count: %d, solaxX1_global.QueryID_count: %d"), solaxX1_global.AddressAssigned, solaxX1_global.QueryData_count, solaxX1_global.SendRetry_count, solaxX1_global.QueryID_count); +// DEBUG_SENSOR_LOG(PSTR("SX1: solaxX1_global.AddressAssigned: %d, solaxX1_global.QueryData_count: %d, solaxX1_global.SendRetry_count: %d"), solaxX1_global.AddressAssigned, solaxX1_global.QueryData_count, solaxX1_global.SendRetry_count); if (solaxX1_global.AddressAssigned) { if (!solaxX1_global.QueryData_count) { // normal periodically query solaxX1_global.QueryData_count = 5; - if (!solaxX1_global.QueryID_count || solaxX1_global.Command_QueryID) { // ID query + if (!solaxX1.SerialNumber[0] || solaxX1_global.Command_QueryID) { // ID query DEBUG_SENSOR_LOG(PSTR("SX1: Send ID query")); solaxX1_QueryIDData(); } else if (solaxX1_global.Command_QueryConfig) { // Config query @@ -562,7 +561,6 @@ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds DEBUG_SENSOR_LOG(PSTR("SX1: Send live query")); solaxX1_QueryLiveData(); } - solaxX1_global.QueryID_count++; // query ID every 256th time } // end normal periodically query solaxX1_global.QueryData_count--; if (!solaxX1_global.SendRetry_count) { // Inverter went "off" From 56243ef720275790a85478d72b05c4b50f32520b Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Sun, 3 Nov 2024 21:31:35 +0100 Subject: [PATCH 076/205] New features for MiElHVAC (#22423) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes * New feature Outdoor Temperature for MiElHVAC * Add Outdoor Temperature * New feature Compressor Frequency for MiElHVAC * Added Outdoor Temperature * Renamed internal properties due typo operating and oprating to operation * New feature Auto Clear Remote Temp for MiElHVAC * This PR add auto clear remote temperature function * This funcion is call on first run and after 10 sec the remote temperature stop refresh its value * Send manually Clear command is also available * change function name, small corrections * added auto clear time configurable using cmnd * Improvements to remote temp, auto clear time for MiElHVAC * Added min = 1000ms and max 600000ms limit to remotetemp auto clear time function * Changed function name to use sam format as other * Added RemoteTemperatureSensor to the sensor * more improvements to auto clear time * Changed RemoteTemperatureSensor to RemoteTemperatureSensorState * Added RemoteTemperatureSensorAutoClearTime to the sensor output * New feature Timers for MiElHVAC * Added Timers to the sensor output: * TimerMode - none, on, off, on_and_off * TimerOn - display time to ON * TimerOnRemaining - display remaining time to ON * TimerOff - display time to OFF * TimerOffRemaining - display remaining time to OFF * New feature for Stage and more for MiElHVAC * Added to sensor output: * Added PrerunStage - on/off, report compressor prepare stage before start working * FanStage - off, quiet, 1, 2, 3 ,4 ,5, report current fan stage * ModeStage - manual(heat, dry, cool, fan_only, heat_isee, dry_isee, cool_isee), auto_fan, auto_heat, auto_cool, report current mode * Renamed Bytes to Settings for raw data * Renamed const UPDATE to SETTINGS * Moved SETTINGS const from miel_hvac_msg_settings to miel_hvac_data_settings * Renamed some functions name to get better code readable * Removed some empty lines * Refactor some structure of code to make more clean and better readable * remove duplicate settings request * New features for MiElHVAC * Changed PrerunStage to OperationStage * Updated map for OperationStage * Updated map for ModeStage * Changed map fan_only to fan * Cleanup --- .../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index 2635cfee5..fe414bd12 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -180,9 +180,12 @@ struct miel_hvac_data_status struct miel_hvac_data_stage { uint8_t _pad1[2]; - uint8_t prerun; -#define MIEL_HVAC_STAGE_PRERUN_OFF 0x00 -#define MIEL_HVAC_STAGE_PRERUN_ON 0x04 + uint8_t operation; +#define MIEL_HVAC_STAGE_OPERATION_NORMAL 0x00 +#define MIEL_HVAC_STAGE_OPERATION_UNKNOWN 0x01 +#define MIEL_HVAC_STAGE_OPERATION_DEFROST 0x02 +#define MIEL_HVAC_STAGE_OPERATION_STANDBY 0x03 +#define MIEL_HVAC_STAGE_OPERATION_PREHEAT 0x04 uint8_t fan; #define MIEL_HVAC_STAGE_FAN_OFF 0x00 #define MIEL_HVAC_STAGE_FAN_1 0x01 @@ -196,6 +199,7 @@ struct miel_hvac_data_stage #define MIEL_HVAC_STAGE_MODE_AUTO_FAN 0x01 #define MIEL_HVAC_STAGE_MODE_AUTO_HEAT 0x02 #define MIEL_HVAC_STAGE_MODE_AUTO_COOL 0x03 +#define MIEL_HVAC_STAGE_MODE_AUTO_LEADER 0x04 }; struct miel_hvac_data @@ -210,7 +214,7 @@ struct miel_hvac_data union { struct miel_hvac_data_settings settings; - struct miel_hvac_data_roomtemp roomtemp;; + struct miel_hvac_data_roomtemp roomtemp; struct miel_hvac_data_timers timers; struct miel_hvac_data_status status; struct miel_hvac_data_stage stage; @@ -243,7 +247,7 @@ CTASSERT(offsetof(struct miel_hvac_data, data.timers.offminutes) == 5); CTASSERT(offsetof(struct miel_hvac_data, data.timers.onminutesremaining) == 6); CTASSERT(offsetof(struct miel_hvac_data, data.timers.offminutesremaining) == 7); -CTASSERT(offsetof(struct miel_hvac_data, data.stage.prerun) == 3); +CTASSERT(offsetof(struct miel_hvac_data, data.stage.operation) == 3); CTASSERT(offsetof(struct miel_hvac_data, data.stage.fan) == 4); CTASSERT(offsetof(struct miel_hvac_data, data.stage.mode) == 5); @@ -403,7 +407,7 @@ static const struct miel_hvac_map miel_hvac_mode_map[] = { {MIEL_HVAC_SETTINGS_MODE_HEAT, "heat"}, {MIEL_HVAC_SETTINGS_MODE_DRY, "dry"}, {MIEL_HVAC_SETTINGS_MODE_COOL, "cool"}, - {MIEL_HVAC_SETTINGS_MODE_FAN, "fan_only"}, + {MIEL_HVAC_SETTINGS_MODE_FAN, "fan"}, {MIEL_HVAC_SETTINGS_MODE_AUTO, "auto"}, {MIEL_HVAC_SETTINGS_MODE_HEAT_ISEE, "heat_isee"}, {MIEL_HVAC_SETTINGS_MODE_DRY_ISEE, "dry_isee"}, @@ -469,9 +473,12 @@ static const struct miel_hvac_map miel_hvac_timer_mode_map[] = { {MIEL_HVAC_TIMER_MODE_BOTH, "on_and_off"}, }; -static const struct miel_hvac_map miel_hvac_stage_prerun_map[] = { - {MIEL_HVAC_STAGE_PRERUN_OFF, "off"}, - {MIEL_HVAC_STAGE_PRERUN_ON, "on"}, +static const struct miel_hvac_map miel_hvac_stage_operation_map[] = { + {MIEL_HVAC_STAGE_OPERATION_NORMAL, "normal"}, + {MIEL_HVAC_STAGE_OPERATION_UNKNOWN, "unknown"}, + {MIEL_HVAC_STAGE_OPERATION_DEFROST, "defrost"}, + {MIEL_HVAC_STAGE_OPERATION_STANDBY, "standby"}, + {MIEL_HVAC_STAGE_OPERATION_PREHEAT, "preheat"}, }; static const struct miel_hvac_map miel_hvac_stage_fan_map[] = { @@ -489,6 +496,7 @@ static const struct miel_hvac_map miel_hvac_stage_mode_map[] = { {MIEL_HVAC_STAGE_MODE_AUTO_FAN, "auto_fan"}, {MIEL_HVAC_STAGE_MODE_AUTO_HEAT, "auto_heat"}, {MIEL_HVAC_STAGE_MODE_AUTO_COOL, "auto_cool"}, + {MIEL_HVAC_STAGE_MODE_AUTO_LEADER, "auto_leader"}, }; enum miel_hvac_parser_state @@ -545,7 +553,6 @@ miel_hvac_update_settings_pending(struct miel_hvac_softc *sc) } static struct miel_hvac_softc *miel_hvac_sc = nullptr; - static void miel_hvac_input_connected(struct miel_hvac_softc *, const void *, size_t); static void miel_hvac_input_data(struct miel_hvac_softc *, const void *, size_t); static void miel_hvac_input_updated(struct miel_hvac_softc *, const void *, size_t); @@ -1078,7 +1085,7 @@ miel_hvac_cmnd_remotetemp(void) update->temp_old = miel_hvac_remotetemp_degc2old(degc); update->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; - remotetemp_last_call_time = control == MIEL_HVAC_REMOTETEMP_SET ? millis() : 0; + remotetemp_last_call_time = control == MIEL_HVAC_REMOTETEMP_SET ? millis() : 0; remotetemp_clear = control == MIEL_HVAC_REMOTETEMP_SET ? true : false; } @@ -1252,7 +1259,7 @@ miel_hvac_input_data(struct miel_hvac_softc *sc, const void *buf, size_t len) break; case MIEL_HVAC_DATA_T_ROOMTEMP: miel_hvac_input_sensor(sc, &sc->sc_roomtemp, d); - break; + break; case MIEL_HVAC_DATA_T_TIMERS: miel_hvac_input_sensor(sc, &sc->sc_timers, d); break; @@ -1516,10 +1523,10 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) const struct miel_hvac_data_stage *stage = &sc->sc_stage.data.stage; char hex[(sizeof(sc->sc_stage) + 1) * 2]; - name = miel_hvac_map_byval(stage->prerun, miel_hvac_stage_prerun_map, nitems(miel_hvac_stage_prerun_map)); + name = miel_hvac_map_byval(stage->operation, miel_hvac_stage_operation_map, nitems(miel_hvac_stage_operation_map)); if (name != NULL) { - ResponseAppend_P(PSTR(",\"PrerunStage\":\"%s\""), name); + ResponseAppend_P(PSTR(",\"OperationStage\":\"%s\""), name); } name = miel_hvac_map_byval(stage->fan, miel_hvac_stage_fan_map, nitems(miel_hvac_stage_fan_map)); From 490c48eefee67107987ffae173f7ff788a736477 Mon Sep 17 00:00:00 2001 From: Norbert <48217146+Noschvie@users.noreply.github.com> Date: Mon, 4 Nov 2024 08:50:20 +0100 Subject: [PATCH 077/205] Add #ifndef for MCP23XXX_ADDR_START and MCP23XXX_ADDR_END (#22424) As discussed in #22410. --- tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino index 04422091f..3182362ad 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino @@ -75,8 +75,12 @@ #define XDRV_67 67 #define XI2C_77 77 // See I2CDEVICES.md +#ifndef MCP23XXX_ADDR_START #define MCP23XXX_ADDR_START 0x20 // 32 +#endif +#ifndef MCP23XXX_ADDR_END #define MCP23XXX_ADDR_END 0x26 // 38 +#endif #define MCP23XXX_MAX_DEVICES 6 From 57d8bea761a347cd3fa47cac441d7b9e7f72ae17 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:23:46 +0100 Subject: [PATCH 078/205] ESP32S3 UART output mode for Tx (#22426) --- CHANGELOG.md | 1 + tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cd6b0ae4..02f1b2b90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. ### Changed ### Fixed +- ESP32S3 UART output mode for Tx ### Removed diff --git a/tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino index f7af10175..0d5545769 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino @@ -149,6 +149,12 @@ void TCPInit(void) { if (!Settings->tcp_baudrate) { Settings->tcp_baudrate = 115200 / 300; } + // patch for ESP32S3 +#if CONFIG_IDF_TARGET_ESP32S3 + pinMode(Pin(GPIO_TCP_TX), OUTPUT); + digitalWrite(Pin(GPIO_TCP_TX), HIGH); + sleep(1); +#endif // CONFIG_IDF_TARGET_ESP32S3 TCPSerial = new TasmotaSerial(Pin(GPIO_TCP_RX), Pin(GPIO_TCP_TX), TasmotaGlobal.seriallog_level ? 1 : 2, 0, TCP_BRIDGE_BUF_SIZE); // set a receive buffer of 256 bytes tcp_serial = TCPSerial->begin(Settings->tcp_baudrate * 300, ConvertSerialConfig(0x7F & Settings->tcp_config)); if (PinUsed(GPIO_TCP_TX_EN)) { From 94c45689a61aa3c9b56270be55f30bea1da962b5 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:31:50 +0100 Subject: [PATCH 079/205] Prepare for virtual I2C (#22427) --- CHANGELOG.md | 2 ++ .../tasmota_xsns_sensor/xsns_109_sgp4x.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino | 33 +++++++++++-------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02f1b2b90..e8495185e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file. ### Breaking Changed ### Changed +- AHT1X/AHT2X/AHT3X ready for virtual I2C +- SGP4X ready for virtual I2C ### Fixed - ESP32S3 UART output mode for Tx diff --git a/tasmota/tasmota_xsns_sensor/xsns_109_sgp4x.ino b/tasmota/tasmota_xsns_sensor/xsns_109_sgp4x.ino index 058b843af..75a7568e3 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_109_sgp4x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_109_sgp4x.ino @@ -81,7 +81,7 @@ void sgp4x_Init(void) uint16_t serialNumber[serialNumberSize]; uint16_t error; - sgp4x.begin(Wire); + sgp4x.begin(I2cGetWire()); error = sgp4x.getSerialNumber(serialNumber, serialNumberSize); if (error) { diff --git a/tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino b/tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino index 976d84b3f..f62e572ee 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino @@ -94,9 +94,10 @@ struct { } aht1x_sensors[AHT1X_MAX_SENSORS]; bool AHT1XWrite(uint8_t aht1x_idx) { - Wire.beginTransmission(aht1x_sensors[aht1x_idx].address); - Wire.write(AHTMeasureCmd, 3); - if (Wire.endTransmission() != 0) + TwoWire &wire = I2cGetWire(); + wire.beginTransmission(aht1x_sensors[aht1x_idx].address); + wire.write(AHTMeasureCmd, 3); + if (wire.endTransmission() != 0) return false; delay(AHT1X_MEAS_DELAY); return true; @@ -104,10 +105,11 @@ bool AHT1XWrite(uint8_t aht1x_idx) { bool AHT1XRead(uint8_t aht1x_idx) { uint8_t data[6]; - Wire.requestFrom(aht1x_sensors[aht1x_idx].address, (uint8_t) 6); + TwoWire &wire = I2cGetWire(); + wire.requestFrom(aht1x_sensors[aht1x_idx].address, (uint8_t) 6); - for(uint8_t i = 0; Wire.available() > 0; i++) { - data[i] = Wire.read(); + for(uint8_t i = 0; wire.available() > 0; i++) { + data[i] = wire.read(); } if (data[0] & 0x80) return false; //device is busy @@ -141,23 +143,26 @@ unsigned char AHT1XReadStatus(uint8_t aht1x_address) { //Wire.beginTransmission(aht1x_address); //Wire.write(0x71); //if (Wire.endTransmission() != 0) return false; - Wire.requestFrom(aht1x_address, (uint8_t) 1); - result = Wire.read(); + TwoWire &wire = I2cGetWire(); + wire.requestFrom(aht1x_address, (uint8_t) 1); + result = wire.read(); return result; } void AHT1XReset(uint8_t aht1x_address) { - Wire.beginTransmission(aht1x_address); - Wire.write(AHTResetCmd); - Wire.endTransmission(); + TwoWire &wire = I2cGetWire(); + wire.beginTransmission(aht1x_address); + wire.write(AHTResetCmd); + wire.endTransmission(); delay(AHT1X_RST_DELAY); } /********************************************************************************************/ bool AHT1XInit(uint8_t aht1x_address) { - Wire.beginTransmission(aht1x_address); - Wire.write(AHTSetCalCmd, 3); - if (Wire.endTransmission() != 0) + TwoWire &wire = I2cGetWire(); + wire.beginTransmission(aht1x_address); + wire.write(AHTSetCalCmd, 3); + if (wire.endTransmission() != 0) return false; delay(AHT1X_CMD_DELAY); if(AHT1XReadStatus(aht1x_address) & 0x08) // Sensor calibrated? From a571ca1db58749244db0f86792c63171bfc29ab6 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:21:01 +0100 Subject: [PATCH 080/205] SCD40 ready for virtual I2C (#22443) --- CHANGELOG.md | 2 ++ tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino | 22 +++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8495185e..ecc057a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file. ### Changed - AHT1X/AHT2X/AHT3X ready for virtual I2C - SGP4X ready for virtual I2C +- SCD40 reduce logging levels +- SCD40 ready for virtual I2C ### Fixed - ESP32S3 UART output mode for Tx diff --git a/tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino b/tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino index 5092ac69f..91b69afeb 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino @@ -117,7 +117,7 @@ void Scd40Detect(void) { if (!I2cSetDevice(SCD40_ADDRESS)) { return; } - scd40.begin(); + scd40.begin(&I2cGetWire()); // don't stop in case of error, try to continue delay(10); // not sure whether this is needed @@ -173,13 +173,13 @@ void Scd40Update(void) case ERROR_SCD40_NO_DATA: scd40DataNotAvailable_count++; - AddLog(LOG_LEVEL_DEBUG, PSTR("SCD40: no data available.")); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SCD40: no data available.")); break; case ERROR_SCD40_CRC_ERROR: scd40CrcError_count++; #ifdef SCD40_DEBUG - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: CRC error, CRC error: %ld, good: %ld, no data: %ld, sc30_reset: %ld, i2c_reset: %ld"), + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: CRC error, CRC error: %ld, good: %ld, no data: %ld, sc30_reset: %ld, i2c_reset: %ld"), scd40CrcError_count, scd40GoodMeas_count, scd40DataNotAvailable_count, scd40Reset_count, scd40i2cReset_count); #endif break; @@ -187,7 +187,7 @@ void Scd40Update(void) default: { scd40ErrorState = SCD40_STATE_ERROR_READ_MEAS; #ifdef SCD40_DEBUG - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: Update: ReadMeasurement error: 0x%lX, counter: %ld"), error, scd40Loop_count); + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: Update: ReadMeasurement error: 0x%lX, counter: %ld"), error, scd40Loop_count); #endif return; } @@ -198,22 +198,22 @@ void Scd40Update(void) case SCD40_STATE_ERROR_READ_MEAS: { #ifdef SCD40_DEBUG - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: (rd) in error state: %d, good: %ld, no data: %ld, sc30 reset: %ld, i2c reset: %ld"), + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: (rd) in error state: %d, good: %ld, no data: %ld, sc30 reset: %ld, i2c reset: %ld"), scd40ErrorState, scd40GoodMeas_count, scd40DataNotAvailable_count, scd40Reset_count, scd40i2cReset_count); - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: not answering, sending soft reset, counter: %ld"), scd40Loop_count); + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: not answering, sending soft reset, counter: %ld"), scd40Loop_count); #endif scd40Reset_count++; error = scd40.stopPeriodicMeasurement(); if (error) { scd40ErrorState = SCD40_STATE_ERROR_SOFT_RESET; #ifdef SCD40_DEBUG - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: stopPeriodicMeasurement got error: 0x%lX"), error); + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: stopPeriodicMeasurement got error: 0x%lX"), error); #endif } else { error = scd40.reinit(); if (error) { #ifdef SCD40_DEBUG - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: resetting got error: 0x%lX"), error); + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: resetting got error: 0x%lX"), error); #endif scd40ErrorState = SCD40_STATE_ERROR_SOFT_RESET; } else { @@ -225,16 +225,16 @@ void Scd40Update(void) case SCD40_STATE_ERROR_SOFT_RESET: { #ifdef SCD40_DEBUG - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: (rst) in error state: %d, good: %ld, no data: %ld, sc30 reset: %ld, i2c reset: %ld"), + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: (rst) in error state: %d, good: %ld, no data: %ld, sc30 reset: %ld, i2c reset: %ld"), scd40ErrorState, scd40GoodMeas_count, scd40DataNotAvailable_count, scd40Reset_count, scd40i2cReset_count); - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: clearing i2c bus")); + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: clearing i2c bus")); #endif scd40i2cReset_count++; error = scd40.clearI2CBus(); if (error) { scd40ErrorState = SCD40_STATE_ERROR_I2C_RESET; #ifdef SCD40_DEBUG - AddLog(LOG_LEVEL_ERROR, PSTR("SCD40: error clearing i2c bus: 0x%lX"), error); + AddLog(LOG_LEVEL_INFO, PSTR("SCD40: error clearing i2c bus: 0x%lX"), error); #endif } else { scd40ErrorState = ERROR_SCD40_NO_ERROR; From 2fd1c0b7fbe96071798f3a489ec2d5b37556bd51 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:54:16 +0100 Subject: [PATCH 081/205] Support for I2C over Serial (#22444) --- CHANGELOG.md | 2 +- .../xdrv_76_serial_i2c.ino | 476 +++++++++++++++--- 2 files changed, 408 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecc057a73..3eb22e453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ All notable changes to this project will be documented in this file. ## [14.3.0.3] 20241031 ### Added -- Support for I2C over Serial, preliminary stub (#22388) +- Support for I2C over Serial ### Changed - ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_76_serial_i2c.ino b/tasmota/tasmota_xdrv_driver/xdrv_76_serial_i2c.ino index 5053803cf..93fcfc6a2 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_76_serial_i2c.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_76_serial_i2c.ino @@ -21,80 +21,233 @@ #define XDRV_76 76 -class TwoWireSerial; +#ifndef I2C_SERIAL_TIMEOUT +#define I2C_SERIAL_TIMEOUT 20 // number of millisecond to wait for a return from MCU +#endif // I2C_SERIAL_TIMEOUT +#ifndef I2C_SERIAL_INIT_TIMEOUT +#define I2C_SERIAL_INIT_TIMEOUT 2000 // number of millisecond to wait for the RP2040 to start +#endif // I2C_SERIAL_INIT_TIMEOUT + +#ifndef I2C_SERIAL_BAUDRATE +#define I2C_SERIAL_BAUDRATE 115200 // good number to start from +#endif // I2C_SERIAL_BAUDRATE + +class TwoWireSerial; // anticipated declaration of class + +// Global structure to keep the global state +// Due to packed structure, it consumes only 8 bytes so we don't use a pointer here struct { - bool active = false; - uint8_t bus = 0; - uint8_t tx = 0; - uint8_t rx = 0; - TwoWireSerial *WireSerial = nullptr; // replacement object for TwoWire -} i2c_serial; + bool active = false; // is I2C_SERIAL feature active + uint8_t bus = 0; // which I2C bus number are we virtualizing: 0 or 1 + uint8_t tx = 0; // GPIO for Serial Tx + uint8_t rx = 0; // GPIO for Serial Rx + TwoWireSerial *wire_serial = nullptr; // instance of the TwoWire instance to be used instead of `Wire` or `Wire1` +} I2C_Serial; +// The class `TwoWireSerial` implements the minimal part of `TwoWire` to be used as a replacement for `Wire` or `Wire1` class TwoWireSerial : public TwoWire { protected: - uint8_t tx; - uint8_t rx; - TasmotaSerial *serial; // serial instance to communicate with SC18IM704 -private: -public: - TwoWireSerial(uint8_t bus_num) : tx(-1), rx(-1), serial(nullptr), TwoWire(bus_num) { - AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: TwoWireSerial(%i)", bus_num); - }; - // ~TwoWireSerial() {}; + uint8_t tx; // GPIO for Serial Tx + uint8_t rx; // GPIO for Serial Rx + TasmotaSerial serial; // TasmotaSerial instance to communicate with SC18IM704 + uint8_t rx_buffer[I2C_BUFFER_LENGTH]; // statically allocated Rx buffer - size of 128 is more than enough here + uint8_t tx_buffer[I2C_BUFFER_LENGTH]; // statically allocated Tx buffer - size of 128 is more than enough here + size_t rx_index; // offset of cursor in rx_buffer + size_t rx_length; // length of data in rx_buffer + size_t tx_length; // length of data in tx_buffer + bool non_stop; // if `true` used for read after write or write after write + uint8_t tx_address; // I2C address for tx_buffer - bool setPins(int _tx, int _rx) { - if (_tx >= 0 && _rx >= 0) { - tx = _tx; - rx = _rx; +public: + // Constructor + // `bus_num` is still unclear whether it's actually needed + TwoWireSerial(uint8_t bus_num, uint8_t _tx, uint8_t _rx) : + tx(_tx), + rx(_rx), + serial(rx, tx), // TasmotaSerial constructor + TwoWire(bus_num) // parent class + {}; + + // Destructor + ~TwoWireSerial() { + // nothing to do here: + // - TasmotaSerial destructor is implcitly called after this + // - buffers are statically allocated so we don't need to free them here + }; + + // bool begin() override {}; -- 'final' cannot be overriden -- don't use !!! + // bool begin(uint8_t address) override{}; -- 'final' cannot be overriden -- don't use !!! + bool end() override { return true; }; + + // Start UART + bool beginSerial() { + // AddLog(LOG_LEVEL_DEBUG_MORE, "ICR: beginSerial tx %i rx %i", tx, rx); + if (tx >= 0 && rx >= 0) { +#if CONFIG_IDF_TARGET_ESP32S3 + pinMode(tx, OUTPUT); + digitalWrite(tx, HIGH); + sleep(1); +#endif // CONFIG_IDF_TARGET_ESP32S3 + serial.begin(I2C_SERIAL_BAUDRATE); return true; } return false; } - - // virtual bool begin() - // virtual bool begin(uint8_t address) override{ Serial.printf(">>>>>>> begin\n"); return true; }; - // virtual bool end() = 0; - bool beginSerial() { - AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: beginSerial"); - if (tx >= 0 && rx >= 0) { - serial = new TasmotaSerial(tx, rx); - if (serial) { - serial->begin(115200); - return true; - } - } - return false; - } - virtual bool setClock(uint32_t freq) override { - AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: setClock(%i) -- ignored", freq); + // Ignore return true; } - virtual void beginTransmission(uint8_t address) override { - AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: beginTransmission(0x%02X)", address); - }; - virtual uint8_t endTransmission(bool stopBit) override { - AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: endTransmission(%i)", stopBit); - return 2; - } - virtual uint8_t endTransmission(void) override { - AddLog(LOG_LEVEL_DEBUG_MORE, "ISR: endTransmission()"); - return 2; + // Internal function to read I2C_STAT internal register and get the state of the last read or write + int32_t read_i2c_stat(void) { + serial.flush(); + serial.write('R'); + serial.write(0x0A); // I2CStat + serial.write('P'); + int32_t r = serial.read(); + uint32_t wait_until = millis() + I2C_SERIAL_TIMEOUT; + while (r < 0 && !TimeReached(wait_until)) { + delay(1); + r = serial.read(); + } + return r; } - // not used, but redefine to avoid any accidental call - virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit) override { return 0; }; - virtual size_t requestFrom(uint8_t address, size_t len) override { return 0; }; + // unused function, but override to NOP just in case + void onReceive(void (*)(int)) override {}; + void onRequest(void (*)(void)) override {}; + + void beginTransmission(uint8_t address) override { + non_stop = false; + tx_address = address; + tx_length = 0; + }; + + /* + https://www.arduino.cc/reference/en/language/functions/communication/wire/endtransmission/ + endTransmission() returns: + 0: success. + 1: data too long to fit in transmit buffer. + 2: received NACK on transmit of address. + 3: received NACK on transmit of data. + 4: other error. + 5: timeout + */ + uint8_t endTransmission(bool stopBit) override { + // AddLog(LOG_LEVEL_DEBUG_MORE, "ICR: endTransmission txAddress=%i txBuffer=%p bufferSize=%i txLength=%i _timeOutMillis=%i stopBit=%i", txAddress, txBuffer, bufferSize, txLength, _timeOutMillis, stopBit); + serial.flush(); + serial.write('S'); // Start I2C + serial.write((tx_address << 1) + 0); // Address for Write + serial.write(tx_length); // length in bytes + for (int32_t i = 0; i < tx_length; i++) { + serial.write(tx_buffer[i]); + } + if (stopBit) { + serial.write('P'); // Stop + } + // Read I2CStat + int32_t r = read_i2c_stat(); + // AddLog(LOG_LEVEL_DEBUG_MORE, "ICR: endTransmission i2c_stat=%i", r); + if (r < 0) { return 4; } // fatal error + r = (r & 0x0F); // keep only 4 low bits + if (r == 0) { return 0; } // OK + if (r == 1) { return 2; } // I2C_NACK_ON_ADDRESS + if (r == 2) { return 3; } // I2C_NACK_ON_DATA + if (r == 3) { return 5; } // I2C_TIME_OUT + return 4; + } + // variant + uint8_t endTransmission() override { + return endTransmission(true); + } + + // override `write` to use statically allocated buffers + size_t write(uint8_t data) override { + if (tx_length >= I2C_BUFFER_LENGTH) { + return 0; + } + tx_buffer[tx_length++] = data; + return 1; + } + + size_t write(const uint8_t *data, size_t quantity) override { + for (size_t i = 0; i < quantity; ++i) { + if (!write(data[i])) { + return i; + } + } + return quantity; + } + + int available() override { + int result = rx_length - rx_index; + return result; + } + int read() override { + int value = -1; + if (rx_index < rx_length) { + value = rx_buffer[rx_index++]; + } + return value; + } + + int peek() override { + int value = -1; + if (rx_index < rx_length) { + value = rx_buffer[rx_index]; + } + return value; + } + + void flush() { + rx_index = 0; + rx_length = 0; + tx_length = 0; + rxIndex = 0; + rxLength = 0; + } + + virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit) override { + if (len > I2C_BUFFER_LENGTH) { + return 0; + } + // AddLog(LOG_LEVEL_DEBUG, "ICR: address=0x%02X read_len=%i r=%02X", address, len); + serial.flush(); + serial.write('S'); // Start I2C + serial.write((address << 1) + 1); // Address for Read + serial.write(len); // length in bytes + serial.write('P'); // Stop + + rx_index = 0; + rx_length = 0; + for (int32_t read_len = 0; read_len < len; read_len++) { + int32_t r = serial.read(); + uint32_t wait_until = millis() + I2C_SERIAL_TIMEOUT; + while (r < 0 && !TimeReached(wait_until)) { + delay(1); + r = serial.read(); + } + if (r >= 0) { + rx_buffer[rx_length++] = r; + } else { + break; + } + } + // AddLog(LOG_LEVEL_DEBUG_MORE, "ICR: requestFrom(addr=%i, len=%i, stop=%i) returned %i bytes", address, len, stopBit, rx_length); + return rx_length; + }; + // Variant + size_t requestFrom(uint8_t address, size_t size) override { + return requestFrom(address, size, true); + } }; // return the original Wire object or the I2C Serial object TwoWire & I2CSerialGetWire(TwoWire & orig_wire, uint8_t bus) { - if (i2c_serial.active && i2c_serial.bus == bus) { - AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Bus%d %p"), bus +1, i2c_serial.WireSerial); - return *i2c_serial.WireSerial; + if (I2C_Serial.active && I2C_Serial.wire_serial && I2C_Serial.bus == bus) { + return *I2C_Serial.wire_serial; } else { return orig_wire; } @@ -105,11 +258,11 @@ TwoWire & I2CSerialGetWire(TwoWire & orig_wire, uint8_t bus) { // - configure serial bus // - register serial bus with Tasmota void I2CSerialInit(void) { - i2c_serial.active = false; + I2C_Serial.active = false; // check if I2C serial is configured on some GPIOs for (uint32_t bus = 0; bus < MAX_I2C; bus++) { if (PinUsed(GPIO_I2C_SER_TX, bus) && PinUsed(GPIO_I2C_SER_RX, bus)) { - if (i2c_serial.active) { + if (I2C_Serial.active) { // Error: I2C Serial was already configured on bus 0, we don't accept a second one AddLog(LOG_LEVEL_ERROR, "I2C: I2C serial can be configured only on 1 bus"); continue; @@ -119,26 +272,43 @@ void I2CSerialInit(void) { AddLog(LOG_LEVEL_ERROR, "I2C: I2C serial failed on bus %i because SDA/SCL already configured", bus + 1); } else { // all good - i2c_serial.bus = bus; - i2c_serial.tx = Pin(GPIO_I2C_SER_TX, bus); - i2c_serial.rx = Pin(GPIO_I2C_SER_RX, bus); - i2c_serial.active = true; + I2C_Serial.bus = bus; + I2C_Serial.tx = Pin(GPIO_I2C_SER_TX, bus); + I2C_Serial.rx = Pin(GPIO_I2C_SER_RX, bus); + I2C_Serial.active = true; } } } // configure serial bus - if (i2c_serial.active) { - i2c_serial.WireSerial = new TwoWireSerial(1); // TODO is it ok to use UART 1 ? - i2c_serial.WireSerial->setPins(i2c_serial.tx, i2c_serial.rx); - if (i2c_serial.WireSerial->beginSerial()) { - TasmotaGlobal.i2c_enabled[i2c_serial.bus] = true; // enable at Tasmota level - AddLog(LOG_LEVEL_INFO, "I2C: I2C serial configured on GPIO TX %i / RX %i for bus %i", i2c_serial.tx, i2c_serial.rx, i2c_serial.bus + 1); + if (I2C_Serial.active) { + I2C_Serial.wire_serial = new TwoWireSerial(1, I2C_Serial.tx, I2C_Serial.rx); // TODO is it ok to use UART 1 ? + if (I2C_Serial.wire_serial->beginSerial()) { + TasmotaGlobal.i2c_enabled[I2C_Serial.bus] = true; // enable at Tasmota level + AddLog(LOG_LEVEL_INFO, "I2C: I2C serial configured on GPIO TX %i / RX %i for bus %i", I2C_Serial.tx, I2C_Serial.rx, I2C_Serial.bus + 1); } else { - delete i2c_serial.WireSerial; - i2c_serial.active = false; + delete I2C_Serial.wire_serial; + I2C_Serial.wire_serial = nullptr; + I2C_Serial.active = false; } } - AddLog(LOG_LEVEL_DEBUG_MORE, "I2C: I2C serial active %i, bus %i, tx %i / rx %i, wire %p", i2c_serial.active, i2c_serial.bus + 1, i2c_serial.tx, i2c_serial.rx, i2c_serial.WireSerial); + // reading I2C_stat to check if connection is alive + if (I2C_Serial.active) { + int32_t r = -1; // result, or -1 of nothing was received + uint32_t wait_until_init = millis() + I2C_SERIAL_INIT_TIMEOUT; + while (r < 0 && !TimeReached(wait_until_init)) { + r = I2C_Serial.wire_serial->read_i2c_stat(); + delay(10); // wait for 10ms before iterating + } + if (r < 0) { + AddLog(LOG_LEVEL_INFO, "I2C: I2C serial failed to communicate with target"); + delete I2C_Serial.wire_serial; + I2C_Serial.wire_serial = nullptr; + I2C_Serial.active = false; + } else { + AddLog(LOG_LEVEL_DEBUG, "I2C: I2C serial initialized"); + } + } + // AddLog(LOG_LEVEL_DEBUG_MORE, "I2C: I2C serial active %i, bus %i, tx %i / rx %i, wire %p", I2C_Serial.active, I2C_Serial.bus + 1, I2C_Serial.tx, I2C_Serial.rx, I2C_Serial.wire_serial); } /*********************************************************************************************\ @@ -150,7 +320,7 @@ bool Xdrv76(uint32_t function) { if (FUNC_PRE_INIT == function) { I2CSerialInit(); - } else if (i2c_serial.active) { + } else if (I2C_Serial.active) { switch (function) { case FUNC_ACTIVE: result = true; @@ -161,3 +331,171 @@ bool Xdrv76(uint32_t function) { } #endif // USE_I2C_SERIAL + + +/********************************************************************************\ + +# below is an example of Micropython code for Seedstudio SenseCap +# that allows to bridge the UART on GPIO 16/17 to I2C on GPIO 20/21 + +from machine import Pin, I2C +from machine import Pin +from machine import UART, Pin +import time + +uart = UART(0, baudrate=115200, tx=Pin(16), rx=Pin(17), timeout=30000, timeout_char=50, txbuf=128, rxbuf=128) +print(f"CFG: UART initialized") + +power_i2c = Pin(18, Pin.OUT) # create output pin on GPIO0 +power_i2c.on() # set pin to "on" (high) level + +i2c = I2C(0, scl=Pin(21), sda=Pin(20), freq=400_000, timeout=1000) + +# print(f"I2C: scan {i2c.scan()}") + +# i2c_stat: +# 0: no error +# 1: I2C_NACK_ON_ADDRESS +# 2: I2C_NACK_ON_DATA +# 3: I2C_TIME_OUT +i2c_stat = 0 +def set_i2c_stat(v): + global i2c_stat + i2c_stat = v + +def get_i2c_stat(): + global i2c_stat + return i2c_stat + + +def ignore_until_P(): + # read uart until none left or 'P' reached + # return last unprocessed char or None + while True: + c = uart.read(1) + if c is None: + return None # end of receive + if c == b'P': + cur_char = None + return None # end reached + +def process_cmd_start(): + # return last unprocessed char or None + addr_b = uart.read(1) + if addr_b is None: print("start: no address sent"); return None + addr = addr_b[0] >> 1 + is_write = not bool(addr_b[0] & 1) + len_b = uart.read(1) + if len_b is None: print("start: no length sent"); return None + len_i = len_b[0] + cmd_next = None + # dispatch depending on READ or WRITE + if is_write: + payload_b = bytes() + if len_i > 0: + payload_b = uart.read(len_i) + if len(payload_b) < len_i: + print(f"start: payload {payload_b} too small, expected {len_i} bytes") + return None + stop_bit = False + cmd_next = uart.read(1) + if cmd_next == b'P': + stop_bit = True + try: + set_i2c_stat(0) + acks_count = i2c.writeto(addr, payload_b, stop_bit) + #print(f"{acks_count=} {len_i=}") + if acks_count < len_i: + set_i2c_stat(2) + else: + print(f"I2C: [0x{addr:02X}] W '{payload_b.hex()}'") + #print(f"{acks_count=} {len_i=} {get_i2c_stat()=}") + except Exception as error: + #print(f"{error=}") + set_i2c_stat(1) # I2C_NACK_ON_ADDRESS + # if 'S' is followed, return to main loop + if cmd_next == b'S': + return cmd_next + else: + # read + payload_b = b'' + #print(f"read: [0x{addr:02X}] {len_i}") + try: + set_i2c_stat(0) + payload_b = i2c.readfrom(addr, len_i, True) + print(f"I2C: [0x{addr:02X}] R '{payload_b.hex()}' {len(payload_b)}/{len_i}") + uart.write(payload_b) + except Exception as error: + print(f"I2C: error while reading from 0x{addr:02X} len={len_i} error '{error}'") + set_i2c_stat(1) # I2C_NACK_ON_ADDRESS + return None + return None + + +def process_cmd_stop(): + # return last unprocessed char or None + return None # do nothing + +def process_cmd_read(): + # return last unprocessed char or None + # we accept only 1 register for now + reg = uart.read(1) + if reg is None: print("read: no register sent"); return None + cmd_next = uart.read(1) + if cmd_next is None or cmd_next != b'P': print("read: unfinished command"); return None + # + reg = reg[0] # convert to number + if reg == 0x0A: # I2CStat + uart.write(int.to_bytes(get_i2c_stat() | 0xF0)) + else: + uart.write(int.to_bytes(0x00)) + return None + +def process_cmd_write(): + # return last unprocessed char or None + print("I2C: ignore 'W' commmand") + return ignore_until_P() + +def process_cmd_version(): + ignore_until_P() + uart.write(b'Tasmota I2C uart bridge 1.0\x00') + return None + +def process_cmd_ignore(): + # return last unprocessed char or None + return ignore_until_P() + +def process_discard(): + # discard all bytes in input + # return last unprocessed char or None + while uart.any() > 1: + uart.read(uart.any()) + return None + +def run(): + cmd = None + while True: + if cmd is None and uart.any() > 0: + cmd = uart.read(1) + if cmd is None: + time.sleep(0.01) + else: + #print(f"SER: received cmd {cmd}") + if cmd == b'S': + cmd = process_cmd_start() + elif cmd == b'P': + cmd = process_cmd_stop() + elif cmd == b'R': + cmd = process_cmd_read() + elif cmd == b'W': + cmd = process_cmd_write() + elif cmd == b'V': + cmd = process_cmd_version() + elif cmd == b'I' or cmd == b'O' or cmd == b'Z': + cmd = process_cmd_ignore() + else: + cmd = process_discard() + +run() + +\********************************************************************************/ From 98cf7f33f7fde6dd6b88a3eedb078e1295481824 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:50:04 +0100 Subject: [PATCH 082/205] Update changelogs --- CHANGELOG.md | 13 +++++++------ RELEASENOTES.md | 7 ++++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eb22e453..2c9e92e31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,23 +6,24 @@ All notable changes to this project will be documented in this file. ## [14.3.0.4] ### Added - DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight` +- Support for I2C over Serial (#22444) ### Breaking Changed ### Changed -- AHT1X/AHT2X/AHT3X ready for virtual I2C -- SGP4X ready for virtual I2C -- SCD40 reduce logging levels -- SCD40 ready for virtual I2C +- AHT1X/AHT2X/AHT3X ready for virtual I2C (#22427) +- SGP4X ready for virtual I2C (#22427) +- SCD40 reduce logging levels (#22443) +- SCD40 ready for virtual I2C (#22443) ### Fixed -- ESP32S3 UART output mode for Tx +- ESP32-S3 UART output mode for Tx (#22426) ### Removed ## [14.3.0.3] 20241031 ### Added -- Support for I2C over Serial +- Support for I2C over Serial, preliminary stub (#22388) ### Changed - ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a1c8e88f5..32a6d4e42 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -123,7 +123,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliTarget` to set light control broadcast, group number or gear number - DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight` - DALI inverted signal configuration using GPIO DALI RX_i/TX_i -- Support for I2C over Serial, preliminary stub [#22388](https://github.com/arendst/Tasmota/issues/22388) +- Support for I2C over Serial [#224444](https://github.com/arendst/Tasmota/issues/224444) - Support for Shelly DALI Dimmer Gen3 - Support for HLK-LD2410S 24GHz smart wave motion sensor [#22253](https://github.com/arendst/Tasmota/issues/22253) - Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) @@ -141,6 +141,10 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Changed - ESP32 Platform from 2024.09.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241030 and IDF to 5.3.1.241024 [#22384](https://github.com/arendst/Tasmota/issues/22384) - ESP32 LVGL library from v9.2.0 to v9.2.2 [#22385](https://github.com/arendst/Tasmota/issues/22385) +- AHT1X/AHT2X/AHT3X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) +- SGP4X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) +- SCD40 reduce logging levels [#22443](https://github.com/arendst/Tasmota/issues/22443) +- SCD40 ready for virtual I2C [#22443](https://github.com/arendst/Tasmota/issues/22443) - Refactored `i2c_enabled` as array [#22387](https://github.com/arendst/Tasmota/issues/22387) - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default @@ -152,5 +156,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 [#22367](https://github.com/arendst/Tasmota/issues/22367) - ESP32 Arduino Core IPv6 zones used by Matter [#22378](https://github.com/arendst/Tasmota/issues/22378) +- ESP32-S3 UART output mode for Tx [#22426](https://github.com/arendst/Tasmota/issues/22426) ### Removed From 4f90c3764a5ef5b5d8ad38bf29b910708f6d10ea Mon Sep 17 00:00:00 2001 From: gemu Date: Fri, 8 Nov 2024 16:51:39 +0100 Subject: [PATCH 083/205] allow knx for scripts (#22429) --- tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino index 35f6d4155..d40c11f34 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino @@ -620,7 +620,7 @@ void KNX_INIT(void) } #endif // USE_ENERGY_SENSOR -#ifdef USE_RULES +#if defined(USE_RULES) || defined(USE_SCRIPT) device_param[KNX_SLOT1-1].show = true; device_param[KNX_SLOT2-1].show = true; device_param[KNX_SLOT3-1].show = true; @@ -718,7 +718,8 @@ void KNX_CB_Action(message_t const &msg, void *arg) } } } -#ifdef USE_RULES + +#if defined(USE_RULES) || defined(USE_SCRIPT) else if ((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT9)) // KNX RX SLOTs (write command) { if (!toggle_inhibit) { @@ -826,7 +827,9 @@ void KNX_CB_Action(message_t const &msg, void *arg) KNX_ANSWER_4BYTE_INT(msg.received_on, round(1000.0 * Energy->total_sum)); } #endif // USE_ENERGY_SENSOR -#ifdef USE_RULES + +#if defined(USE_RULES) || defined(USE_SCRIPT) + else if ((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT9)) // KNX RX SLOTs (read command) { if (!toggle_inhibit) { From ff0d003a246af5326e977c465c041fb7690209a1 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Fri, 8 Nov 2024 16:52:04 +0100 Subject: [PATCH 084/205] Fix Standby Stage for MiElHVAC (#22430) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes * New feature Outdoor Temperature for MiElHVAC * Add Outdoor Temperature * New feature Compressor Frequency for MiElHVAC * Added Outdoor Temperature * Renamed internal properties due typo operating and oprating to operation * New feature Auto Clear Remote Temp for MiElHVAC * This PR add auto clear remote temperature function * This funcion is call on first run and after 10 sec the remote temperature stop refresh its value * Send manually Clear command is also available * change function name, small corrections * added auto clear time configurable using cmnd * Improvements to remote temp, auto clear time for MiElHVAC * Added min = 1000ms and max 600000ms limit to remotetemp auto clear time function * Changed function name to use sam format as other * Added RemoteTemperatureSensor to the sensor * more improvements to auto clear time * Changed RemoteTemperatureSensor to RemoteTemperatureSensorState * Added RemoteTemperatureSensorAutoClearTime to the sensor output * New feature Timers for MiElHVAC * Added Timers to the sensor output: * TimerMode - none, on, off, on_and_off * TimerOn - display time to ON * TimerOnRemaining - display remaining time to ON * TimerOff - display time to OFF * TimerOffRemaining - display remaining time to OFF * New feature for Stage and more for MiElHVAC * Added to sensor output: * Added PrerunStage - on/off, report compressor prepare stage before start working * FanStage - off, quiet, 1, 2, 3 ,4 ,5, report current fan stage * ModeStage - manual(heat, dry, cool, fan_only, heat_isee, dry_isee, cool_isee), auto_fan, auto_heat, auto_cool, report current mode * Renamed Bytes to Settings for raw data * Renamed const UPDATE to SETTINGS * Moved SETTINGS const from miel_hvac_msg_settings to miel_hvac_data_settings * Renamed some functions name to get better code readable * Removed some empty lines * Refactor some structure of code to make more clean and better readable * remove duplicate settings request * New features for MiElHVAC * Changed PrerunStage to OperationStage * Updated map for OperationStage * Updated map for ModeStage * Changed map fan_only to fan * Cleanup * Fix Standby Stage for MiElHVAC --- tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index fe414bd12..17de2e460 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -184,8 +184,9 @@ struct miel_hvac_data_stage #define MIEL_HVAC_STAGE_OPERATION_NORMAL 0x00 #define MIEL_HVAC_STAGE_OPERATION_UNKNOWN 0x01 #define MIEL_HVAC_STAGE_OPERATION_DEFROST 0x02 -#define MIEL_HVAC_STAGE_OPERATION_STANDBY 0x03 +#define MIEL_HVAC_STAGE_OPERATION_UNKNOWN1 0x03 #define MIEL_HVAC_STAGE_OPERATION_PREHEAT 0x04 +#define MIEL_HVAC_STAGE_OPERATION_STANDBY 0x08 uint8_t fan; #define MIEL_HVAC_STAGE_FAN_OFF 0x00 #define MIEL_HVAC_STAGE_FAN_1 0x01 From 245da3918ab3b706450684da620fa076acc008c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 8 Nov 2024 14:57:47 -0100 Subject: [PATCH 085/205] Fix display dump option in script version response (#22434) --- tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino index 3d2e33d84..254f03e10 100755 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino @@ -10259,7 +10259,7 @@ uint32_t options = 0; #ifdef USE_SCRIPT_I2C options |= 0x00400000; #endif -#ifdef USE_DSIPLAY_DUMP +#ifdef USE_DISPLAY_DUMP options |= 0x00800000; #endif #ifdef USE_SCRIPT_SERIAL From 5fac24a5f6d5535f74061834682b9f729afaa005 Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:04:27 +0100 Subject: [PATCH 086/205] [Solax X1] Optimize serial receive (#22440) Serial receive: More stable, more simple and less code --- .../tasmota_xnrg_energy/xnrg_12_solaxX1.ino | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino index 57a138f29..5e69d278d 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino @@ -197,35 +197,21 @@ void solaxX1_RS485SendRaw(uint8_t *SendBuffer, uint8_t DataLen, uint8_t CRCflag) } bool solaxX1_RS485Receive(uint8_t *ReadBuffer) { - uint32_t SerWatchdogTime; - - // Read header + uint8_t SerAvial; uint8_t len = 0; - SerWatchdogTime = millis(); - while (len < 2) { // read exact length because of unaccurate timing of the inverter - if (solaxX1Serial->available()) ReadBuffer[len++] = (uint8_t)solaxX1Serial->read(); - if (millis() > (SerWatchdogTime + 1000)) return true; // No data received -> bail out + + while (SerAvial = solaxX1Serial->available()) { + while (SerAvial--) { + ReadBuffer[len++] = (uint8_t)solaxX1Serial->read(); + } + delay(10); // wait for more data because of slowness of the inverter } + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, ReadBuffer, len); // Check and set meter mode solaxX1_SwitchMeterMode((ReadBuffer[0] == 0x01 || ReadBuffer[0] == 0x02) && (ReadBuffer[1] == 0x03 || ReadBuffer[1] == 0x04)); + if (solaxX1_global.MeterMode) return false; // Ignore checksum in metermode - // Read data in meter mode - if (solaxX1_global.MeterMode) { // Metermode - SerWatchdogTime = millis(); - while (len < 8) { // read exact length because of unaccurate timing of the inverter - if (solaxX1Serial->available()) ReadBuffer[len++] = (uint8_t)solaxX1Serial->read(); - if (millis() > (SerWatchdogTime + 1000)) return true; // No data received -> bail out - } - AddLogBuffer(LOG_LEVEL_DEBUG_MORE, ReadBuffer, len); - return false; // Ignore checksum - } // end Metermode - - // Process normal receive - while (solaxX1Serial->available()) { - ReadBuffer[len++] = (uint8_t)solaxX1Serial->read(); - } - AddLogBuffer(LOG_LEVEL_DEBUG_MORE, ReadBuffer, len); uint16_t crc = solaxX1_calculateCRC(ReadBuffer, len - 2); // calculate out crc bytes return !(ReadBuffer[len - 1] == lowByte(crc) && ReadBuffer[len - 2] == highByte(crc)); } @@ -550,7 +536,7 @@ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds // DEBUG_SENSOR_LOG(PSTR("SX1: solaxX1_global.AddressAssigned: %d, solaxX1_global.QueryData_count: %d, solaxX1_global.SendRetry_count: %d"), solaxX1_global.AddressAssigned, solaxX1_global.QueryData_count, solaxX1_global.SendRetry_count); if (solaxX1_global.AddressAssigned) { if (!solaxX1_global.QueryData_count) { // normal periodically query - solaxX1_global.QueryData_count = 5; + solaxX1_global.QueryData_count = 3; if (!solaxX1.SerialNumber[0] || solaxX1_global.Command_QueryID) { // ID query DEBUG_SENSOR_LOG(PSTR("SX1: Send ID query")); solaxX1_QueryIDData(); From 2f3808adc9ebfbcddc8ebe166ceeabe11d3b1f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 8 Nov 2024 15:15:03 -0100 Subject: [PATCH 087/205] Use standard `var` spelling for reactive power unit (#22435) - https://en.wikipedia.org/wiki/Volt-ampere#Volt-ampere_reactive - https://engineering.electrical-equipment.org/energy-efficiency-kvar/kvar-or-kvar.html --- .../energy_modbus_configs/value_pairs_description.md | 4 ++-- tasmota/language/af_AF.h | 4 ++-- tasmota/language/ca_AD.h | 4 ++-- tasmota/language/cs_CZ.h | 4 ++-- tasmota/language/de_DE.h | 4 ++-- tasmota/language/el_GR.h | 4 ++-- tasmota/language/en_GB.h | 4 ++-- tasmota/language/es_ES.h | 4 ++-- tasmota/language/fr_FR.h | 4 ++-- tasmota/language/fy_NL.h | 4 ++-- tasmota/language/he_HE.h | 4 ++-- tasmota/language/hu_HU.h | 4 ++-- tasmota/language/it_IT.h | 4 ++-- tasmota/language/ko_KO.h | 4 ++-- tasmota/language/nl_NL.h | 4 ++-- tasmota/language/pl_PL.h | 4 ++-- tasmota/language/pt_BR.h | 4 ++-- tasmota/language/pt_PT.h | 4 ++-- tasmota/language/ro_RO.h | 4 ++-- tasmota/language/sk_SK.h | 4 ++-- tasmota/language/sv_SE.h | 4 ++-- tasmota/language/tr_TR.h | 4 ++-- tasmota/language/vi_VN.h | 4 ++-- tasmota/language/zh_CN.h | 2 +- tasmota/language/zh_TW.h | 4 ++-- tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino | 2 +- .../tasmota_xdrv_driver/xdrv_12_home_assistant.ino | 2 +- .../tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino | 4 ++-- .../xdrv_87_esp32_sonoff_tm1621.ino | 2 +- tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino | 4 ++-- tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino | 8 ++++---- tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino | 12 ++++++------ tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino | 2 +- tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino | 6 +++--- tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino | 10 +++++----- 36 files changed, 76 insertions(+), 76 deletions(-) diff --git a/tasmota/energy_modbus_configs/value_pairs_description.md b/tasmota/energy_modbus_configs/value_pairs_description.md index 67a73dee2..3b7bfedcc 100644 --- a/tasmota/energy_modbus_configs/value_pairs_description.md +++ b/tasmota/energy_modbus_configs/value_pairs_description.md @@ -90,8 +90,8 @@ D - Number of decimals for floating point presentation (0 to 20) or a code correspondig to Tasmota resolution command settings: 21 - VoltRes (V) 22 - AmpRes (A) - 23 - WattRes (W, VA, VAr) - 24 - EnergyRes (kWh, kVAh, kVArh) + 23 - WattRes (W, VA, var) + 24 - EnergyRes (kWh, kVAh, kvarh) 25 - FreqRes (Hz) 26 - TempRes (C, F) 27 - HumRes (%) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index cad4d22a4..8efd1ff09 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import reaktief" #define D_EXPORT_REACTIVE "Uitvoer reaktief" #define D_TOTAL_REACTIVE "Totaal reaktief" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Totaal aktief" #define D_RESETTABLE_TOTAL_ACTIVE "Totaal aktief (RST)" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index fe0ffe9f5..54880bebe 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Importat Reactiva" #define D_EXPORT_REACTIVE "Exportat Reactiva" #define D_TOTAL_REACTIVE "Total Reactiva" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Graus" #define D_TOTAL_ACTIVE "Total Activa" #define D_RESETTABLE_TOTAL_ACTIVE "Total Activa (RST)" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 6685140f2..ae48211ef 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sektory" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index c6d46dad0..e186de688 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "Sektoren" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Importiere Blind" #define D_EXPORT_REACTIVE "Exportiere Blind" #define D_TOTAL_REACTIVE "Total Blind" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Grad" #define D_TOTAL_ACTIVE "Total Wirk" #define D_RESETTABLE_TOTAL_ACTIVE "Total Wirk (RST)" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 4933d5f37..782b1acb9 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 2377cd87b..c66232eaa 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 7616129c9..dba5a1d54 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "seg" #define D_UNIT_SECTORS "sectores" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "P. Reactiva Entrante" #define D_EXPORT_REACTIVE "P. Reactiva Saliente" #define D_TOTAL_REACTIVE "P. Reactiva Total" -#define D_UNIT_KWARH "kVArH" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Grados" #define D_TOTAL_ACTIVE "P. Total Activa" #define D_RESETTABLE_TOTAL_ACTIVE "P. Total Activa (RST)" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 47d768b6f..2a0b293d9 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -1060,7 +1060,7 @@ #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "secteurs" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1082,7 +1082,7 @@ #define D_IMPORT_REACTIVE "Énergie réa conso" #define D_EXPORT_REACTIVE "Énergie réa fournie" #define D_TOTAL_REACTIVE "Énergie réa totale" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "°" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 1a7e8c27a..b461da25f 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectoren" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Blind ymportearje" #define D_EXPORT_REACTIVE "Blind eksportearje" #define D_TOTAL_REACTIVE "Hielendal blyn" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Hielendal wier" #define D_RESETTABLE_TOTAL_ACTIVE "Hielendal wier (RST)" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 38289725a..b501c6978 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index b9e5d5b62..8530e60c3 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -1062,7 +1062,7 @@ #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "szektorok" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1084,7 +1084,7 @@ #define D_IMPORT_REACTIVE "Bejövő reaktív" #define D_EXPORT_REACTIVE "Kimenő reaktív" #define D_TOTAL_REACTIVE "Összes reaktív" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "fok" #define D_TOTAL_ACTIVE "Összes aktív" #define D_RESETTABLE_TOTAL_ACTIVE "Összes aktív (RST)" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 6f7895b06..d12030865 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "settori" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Potenza reattiva importata" #define D_EXPORT_REACTIVE "Potenza reattiva esportata" #define D_TOTAL_REACTIVE "Potenza reattiva totale" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "°" #define D_TOTAL_ACTIVE "Potenza attiva totale" #define D_RESETTABLE_TOTAL_ACTIVE "Potenza attiva totale (RST)" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 063ff973a..4404b3b18 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "초" #define D_UNIT_SECTORS "섹터" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index f253566eb..527389197 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectoren" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import blind" #define D_EXPORT_REACTIVE "Export blind" #define D_TOTAL_REACTIVE "Totaal blind" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Totaal werkelijk" #define D_RESETTABLE_TOTAL_ACTIVE "Totaal werkelijk (RST)" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index e117468e4..2be37fe0b 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sektory" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Bierna pobrana" #define D_EXPORT_REACTIVE "Bierna oddana" #define D_TOTAL_REACTIVE "Bierna całkowita" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Stopni" #define D_TOTAL_ACTIVE "Całkowita czynna" #define D_RESETTABLE_TOTAL_ACTIVE "Całkowita czynna (RST)" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 32a0fed1c..4327aec5b 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "setores" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "W/h" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Importar Reativo" #define D_EXPORT_REACTIVE "Exportar Reativo" #define D_TOTAL_REACTIVE "Reativo total" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Ativo" #define D_RESETTABLE_TOTAL_ACTIVE "Total Activo (RST)" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 2add60210..f659ed236 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "setores" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Reativo importado" #define D_EXPORT_REACTIVE "Reativo exportado" #define D_TOTAL_REACTIVE "Reactivo total" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Ativo" #define D_RESETTABLE_TOTAL_ACTIVE "Total Ativo (RST)" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 7cca75c10..d0be73bd4 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactiv" #define D_EXPORT_REACTIVE "Export Reactiv" #define D_TOTAL_REACTIVE "Total Reactiv" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Activ" #define D_RESETTABLE_TOTAL_ACTIVE "Total Activ (RST)" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 949758bdf..3bb13d21a 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sek" #define D_UNIT_SECTORS "sektory" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 9025ebdbb..2c0ddedaa 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sek" #define D_UNIT_SECTORS "sektorer" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import reaktiv" #define D_EXPORT_REACTIVE "Export reaktiv" #define D_TOTAL_REACTIVE "Total reaktiv" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total aktiv" #define D_RESETTABLE_TOTAL_ACTIVE "Total aktiv (RST)" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index c1b0b462e..3c8a01f11 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index caa1075ba..5cc64f7f3 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 6a1166f9f..3f6742a79 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "秒" #define D_UNIT_SECTORS "扇区" #define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VAR "var" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" #define D_UNIT_WATTHOUR "Wh" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index e6254ce49..dd6e80fcd 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -1059,7 +1059,7 @@ #define D_UNIT_SECOND "秒" #define D_UNIT_SECTORS "磁區" #define D_UNIT_VA "伏安(VA)" -#define D_UNIT_VAR "乏爾(VAr)" +#define D_UNIT_VAR "乏爾(var)" #define D_UNIT_VOLT "伏特" #define D_UNIT_WATT "瓦特" #define D_UNIT_WATTHOUR "瓦小時" @@ -1081,7 +1081,7 @@ #define D_IMPORT_REACTIVE "Import Reactive" #define D_EXPORT_REACTIVE "Export Reactive" #define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" +#define D_UNIT_KWARH "kvarh" #define D_UNIT_ANGLE "Deg" #define D_TOTAL_ACTIVE "Total Active" #define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)" diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino index eb07c4fb2..a26644832 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino @@ -80,7 +80,7 @@ typedef struct { float current[ENERGY_MAX_PHASES]; // 123.123 A float active_power[ENERGY_MAX_PHASES]; // 123.1 W float apparent_power[ENERGY_MAX_PHASES]; // 123.1 VA - float reactive_power[ENERGY_MAX_PHASES]; // 123.1 VAr + float reactive_power[ENERGY_MAX_PHASES]; // 123.1 var float power_factor[ENERGY_MAX_PHASES]; // 0.12 float frequency[ENERGY_MAX_PHASES]; // 123.1 Hz float import_active[ENERGY_MAX_PHASES]; // 123.123 kWh diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index 5d03055b7..6b7423329 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -157,7 +157,7 @@ typedef struct { float current[ENERGY_MAX_PHASES]; // 123.123 A float active_power[ENERGY_MAX_PHASES]; // 123.1 W float apparent_power[ENERGY_MAX_PHASES]; // 123.1 VA - float reactive_power[ENERGY_MAX_PHASES]; // 123.1 VAr + float reactive_power[ENERGY_MAX_PHASES]; // 123.1 var float power_factor[ENERGY_MAX_PHASES]; // 0.12 float frequency[ENERGY_MAX_PHASES]; // 123.1 Hz float import_active[ENERGY_MAX_PHASES]; // 123.123 kWh diff --git a/tasmota/tasmota_xdrv_driver/xdrv_12_home_assistant.ino b/tasmota/tasmota_xdrv_driver/xdrv_12_home_assistant.ino index d65d6a22f..b5442a452 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_12_home_assistant.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_12_home_assistant.ino @@ -48,7 +48,7 @@ const char kHAssJsonSensorUnits[] PROGMEM = "||||" "VA|%|A|cm|Hz|%|lux|" "%|ppd|ppd|ppd|ppd|ppd|ppd|µg/m³|µg/m³|µg/m³|Cos φ|W| |" - "VAr|kWh|kWh|V|kg|kWh|" + "var|kWh|kWh|V|kg|kWh|" "ppm|ppm|ppb|R|G|B|" D_UNIT_KELVIN "| |"; const char kHAssJsonSensorDevCla[] PROGMEM = diff --git a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino index 657c53660..592856851 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino @@ -247,7 +247,7 @@ typedef struct { float current[SSPM_MAX_MODULES][4]; // 123.12 A float active_power[SSPM_MAX_MODULES][4]; // 123.12 W float apparent_power[SSPM_MAX_MODULES][4]; // 123.12 VA - float reactive_power[SSPM_MAX_MODULES][4]; // 123.12 VAr + float reactive_power[SSPM_MAX_MODULES][4]; // 123.12 var float power_factor[SSPM_MAX_MODULES][4]; // 0.12 float energy_today[SSPM_MAX_MODULES][4]; // 12345 kWh float energy_total[SSPM_MAX_MODULES][4]; // 12345 kWh total energy since last 6 month!!! @@ -1561,7 +1561,7 @@ void SSPMHandleReceivedData(void) { Sspm->current[module][channel] = SspmBuffer[offset] + (float)SspmBuffer[offset +1] / 100; // x.xxA Sspm->voltage[module][channel] = SSPMGetValue(&SspmBuffer[offset +2]); // x.xxV Sspm->active_power[module][channel] = SSPMGetValue(&SspmBuffer[offset +5]); // x.xxW - Sspm->reactive_power[module][channel] = SSPMGetValue(&SspmBuffer[offset +8]); // x.xxVAr + Sspm->reactive_power[module][channel] = SSPMGetValue(&SspmBuffer[offset +8]); // x.xxvar Sspm->apparent_power[module][channel] = SSPMGetValue(&SspmBuffer[offset +11]); // x.xxVA float power_factor = (Sspm->active_power[module][channel] && Sspm->apparent_power[module][channel]) ? Sspm->active_power[module][channel] / Sspm->apparent_power[module][channel] : 0; if (power_factor > 1) { power_factor = 1; } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino b/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino index 327b0d855..e986fab40 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino @@ -599,7 +599,7 @@ void CmndDspLine(void) { // Example 2: PZEM016 serial connected (GPIO25 = PZEM0XX Tx, GPIO26 = PZEM016 Rx) // {"ENERGY":{"TotalStartTime":"2022-07-05T16:01:39","Total":0.000,"Yesterday":0.000,"Today":0.000,"Power":0.00,"ApparentPower":0.00,"ReactivePower":0.00,"Factor":0.00,"Frequency":50,"Voltage":231.7,"Current":0.000}} // index: 1 2 3 4 5 6 7 8 9 10 11 12 - // unit: 0 0 4 (kWh) 4 (kWh) 4 (kWh) 4 (W) 0 (VA) 0 (VAr) 0 0 3 (V) 3 (A) + // unit: 0 0 4 (kWh) 4 (kWh) 4 (kWh) 4 (W) 0 (VA) 0 (var) 0 0 3 (V) 3 (A) TM1621GetSensors(1); } } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino index 30330d1fe..26f5f61ec 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino @@ -462,10 +462,10 @@ void Ade7953Init(void) { } } #ifdef USE_ESP32_SPI - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: Chip%d CalibRegs%c V %d, I %d, W %d, VA %d, VAr %d, Ph %d"), + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: Chip%d CalibRegs%c V %d, I %d, W %d, VA %d, var %d, Ph %d"), chip +1, 'A'+channel, regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]); #else - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: CalibRegs%c V %d, I %d, W %d, VA %d, VAr %d, Ph %d"), + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: CalibRegs%c V %d, I %d, W %d, VA %d, var %d, Ph %d"), 'A'+channel, regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]); #endif // USE_ESP32_SPI } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino b/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino index 9264be095..21c436a77 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino @@ -54,8 +54,8 @@ const uint16_t sdm120_start_addresses[] { 0X0048, // SDM220_IMPORT_ACTIVE [kWh] 0X004A, // SDM220_EXPORT_ACTIVE [kWh] - 0X004C, // SDM220_IMPORT_REACTIVE [kVArh] - 0X004E, // SDM220_EXPORT_REACTIVE [kVArh] + 0X004C, // SDM220_IMPORT_REACTIVE [kvarh] + 0X004E, // SDM220_EXPORT_REACTIVE [kvarh] 0X0024 // SDM220_PHASE_ANGLE [Degree] }; @@ -138,11 +138,11 @@ void SDM120Every250ms(void) break; case 10: - Sdm120.import_reactive = value; // 172.750 kVArh + Sdm120.import_reactive = value; // 172.750 kvarh break; case 11: - Sdm120.export_reactive = value; // 2.844 kVArh + Sdm120.export_reactive = value; // 2.844 kvarh break; case 12: diff --git a/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino b/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino index 45174c976..38d708ebc 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino @@ -80,9 +80,9 @@ const uint16_t sdm630_start_addresses[] { 0x000C, // + - + W Phase 1 power 0x000E, // + - + W Phase 2 power 0x0010, // + - - W Phase 3 power - 0x0018, // + - + VAr Phase 1 volt amps reactive - 0x001A, // + - - VAr Phase 2 volt amps reactive - 0x001C, // + - - VAr Phase 3 volt amps reactive + 0x0018, // + - + var Phase 1 volt amps reactive + 0x001A, // + - - var Phase 2 volt amps reactive + 0x001C, // + - - var Phase 3 volt amps reactive 0x001E, // + - + Phase 1 power factor 0x0020, // + - - Phase 2 power factor 0x0022, // + - - Phase 3 power factor @@ -165,9 +165,9 @@ void SDM630Every250ms(void) Energy->apparent_power[2] = convBufToFloat(&buffer[47]); // + - - VA Phase 3 volt amps //0x0018 - Energy->reactive_power[0] = convBufToFloat(&buffer[51]); // + - + VAr Phase 1 volt amps reactive - Energy->reactive_power[1] = convBufToFloat(&buffer[55]); // + - - VAr Phase 2 volt amps reactive - Energy->reactive_power[2] = convBufToFloat(&buffer[59]); // + - - VAr Phase 3 volt amps reactive + Energy->reactive_power[0] = convBufToFloat(&buffer[51]); // + - + var Phase 1 volt amps reactive + Energy->reactive_power[1] = convBufToFloat(&buffer[55]); // + - - var Phase 2 volt amps reactive + Energy->reactive_power[2] = convBufToFloat(&buffer[59]); // + - - var Phase 3 volt amps reactive //0x001E Energy->power_factor[0] = convBufToFloat(&buffer[63]); // + - + Phase 1 power factor diff --git a/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino b/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino index 9d56c7b08..7d8a08144 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino @@ -24,7 +24,7 @@ * (and bidirectional energy counting - enabled by RS485). * It measure: Active energy imported AE+ [kWh] , Reactive energy imported RE+ [kvarh], * Voltage V [V], Current I [A], Frequency F [Hz], power factor (aka "cos-phi"), - * Active power P [kW], Reactive power Q [kVAr], Apparent power S [kVA], + * Active power P [kW], Reactive power Q [kvar], Apparent power S [kVA], * *Active energy exported AE- [kWh] (when meter is switched to bi-directional counting then * reactive energy imported register contains value of Active energy exported). * diff --git a/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino b/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino index de67879a7..3dbb082da 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino @@ -54,9 +54,9 @@ const uint16_t we517_start_addresses[] { /* 6 */ 0x001E, // + - + kW Phase 1 power /* 7 */ 0x0020, // + - + kW Phase 2 power /* 8 */ 0x0022, // + - - kW Phase 3 power - /* 9 */ 0x0026, // + - + VAr Phase 1 volt amps reactive - /* 10 */ 0x0028, // + - - VAr Phase 2 volt amps reactive - /* 11 */ 0x002A, // + - - VAr Phase 3 volt amps reactive + /* 9 */ 0x0026, // + - + var Phase 1 volt amps reactive + /* 10 */ 0x0028, // + - - var Phase 2 volt amps reactive + /* 11 */ 0x002A, // + - - var Phase 3 volt amps reactive /* 12 */ 0x0036, // + - + Phase 1 power factor /* 13 */ 0x0038, // + - - Phase 2 power factor /* 14 */ 0x003A, // + - - Phase 3 power factor diff --git a/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino b/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino index 5c6cd19ab..18054e175 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino @@ -53,7 +53,7 @@ const uint16_t sdm230_start_addresses[] { 0x0006, // SDM230_CURRENT [A] 0x000C, // SDM230_POWER (Active) [W] 0x0012, // SDM230_POWER (Apparent) G [VA] - 0x0018, // SDM230_POWER (Reactive) [VAr] + 0x0018, // SDM230_POWER (Reactive) [var] 0x001E, // SDM230_POWER_FACTOR 0x0046, // SDM230_FREQUENCY [Hz] 0X0048, // SDM230_IMPORT_ACTIVE [kWh] @@ -68,10 +68,10 @@ const uint16_t sdm230_start_addresses[] { #endif // SDM230_MORE_REGS // for documentation / further use or implementation -// 0X0158, // SDM230_TOTAL_ENERGY_REACTIVE [kVArh] -// 0X0182, // SDM230_RESETTABLE_TOTAL_ENERGY_REACTIVE [kVArh] -// 0X004C, // SDM230_IMPORT_REACTIVE [kVArh] -// 0X004E, // SDM230_EXPORT_REACTIVE [kVArh] +// 0X0158, // SDM230_TOTAL_ENERGY_REACTIVE [kvarh] +// 0X0182, // SDM230_RESETTABLE_TOTAL_ENERGY_REACTIVE [kvarh] +// 0X004C, // SDM230_IMPORT_REACTIVE [kvarh] +// 0X004E, // SDM230_EXPORT_REACTIVE [kvarh] // 0X0054, // SDM230_TOTAL_DEMAND_POWER_ACTIVE [W] // 0X0058, // SDM230_IMPORT_DEMAND_POWER_ACTIVE [W] // 0X005A, // SDM230_MAXIMUM_IMPORT_DEMAND_POWER_ACTIVE [W] From feff388f03d84bbe66c38018d139112f234a75cd Mon Sep 17 00:00:00 2001 From: AIexBV <44845998+AIexBV@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:21:05 +0100 Subject: [PATCH 088/205] Enable deep sleep (standby) for VL53L0X (#22441) * Enable deep sleep (standby) for VL53L0X * Some renamings --- .../tasmota_xsns_sensor/xsns_45_vl53l0x.ino | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino b/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino index 55882066c..922bb7732 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino @@ -79,13 +79,17 @@ struct { uint16_t distance; uint16_t distance_prev; uint16_t buffer[5]; - uint8_t ready = 0; + bool ready = false; uint8_t index; } Vl53l0x_data[VL53LXX_MAX_SENSORS]; bool VL53L0X_xshut = false; bool VL53L0X_detected = false; +#ifdef USE_DEEPSLEEP +bool VL53L0X_standby = false; // Prevent updating measurments once VL53L0X has been put to standby (just before ESP enters deepsleep) +#endif + /********************************************************************************************/ void Vl53l0Detect(void) { @@ -133,7 +137,7 @@ void Vl53l0Detect(void) { // ms (e.g. sensor.startContinuous(100)). VL53L0X_device[i].startContinuous(); - Vl53l0x_data[i].ready = 1; + Vl53l0x_data[i].ready = true; Vl53l0x_data[i].index = 0; VL53L0X_detected = true; if (!VL53L0X_xshut) { break; } @@ -145,6 +149,10 @@ void Vl53l0Detect(void) { } void Vl53l0Every_250MSecond(void) { +#ifdef USE_DEEPSLEEP + // Prevent updating measurments once VL53L0X has been put to sleep (just before ESP enters deepsleep) + if (VL53L0X_standby) return; +#endif for (uint32_t i = 0; i < VL53LXX_MAX_SENSORS; i++) { if (PinUsed(GPIO_VL53LXX_XSHUT1, i) || (!VL53L0X_xshut)) { uint16_t dist = VL53L0X_device[i].readRangeContinuousMillimeters(); @@ -188,6 +196,10 @@ void Vl53l0Every_250MSecond(void) { #ifdef USE_DOMOTICZ void Vl53l0Every_Second(void) { +#ifdef USE_DEEPSLEEP + // Prevent updating measurments once VL53L0X has been put to sleep (just before ESP enters deepsleep) + if (VL53L0X_standby) return; +#endif if (abs(Vl53l0x_data[0].distance - Vl53l0x_data[0].distance_prev) > 8) { Vl53l0x_data[0].distance_prev = Vl53l0x_data[0].distance; float distance = (float)Vl53l0x_data[0].distance / 10; // cm @@ -225,6 +237,28 @@ void Vl53l0Show(boolean json) { #endif // USE_DOMOTICZ } +#ifdef USE_DEEPSLEEP + +void VL53L0EnterStandby(void) { + if (DeepSleepEnabled()) { + for (uint32_t i = 0; i < VL53LXX_MAX_SENSORS; i++) { + if (PinUsed(GPIO_VL53LXX_XSHUT1, i) || (!VL53L0X_xshut)) { + if (Vl53l0x_data[i].ready) { + // VL53L0X_device[i].stopContinuous(); + // Calling stopContinuous() does not lead to a stable standby state. + // The current is approx. 300 µA, but should be much lower. + // Restart is bumpy and sometimes blocks the startup sequence completely. + VL53L0X_device[i].init(); + Vl53l0x_data[i].ready = false; + } + } + } + VL53L0X_standby = true; + } +} + +#endif // USE_DEEPSLEEP + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -255,6 +289,11 @@ bool Xsns45(uint32_t function) { Vl53l0Show(0); break; #endif // USE_WEBSERVER +#ifdef USE_DEEPSLEEP + case FUNC_SAVE_BEFORE_RESTART: + VL53L0EnterStandby(); + break; +#endif // USE_DEEPSLEEP } } return result; From 19e15e21aaa70de5f931195e6d9df2733af29718 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:38:31 +0100 Subject: [PATCH 089/205] Update changelogs --- CHANGELOG.md | 4 ++++ RELEASENOTES.md | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c9e92e31..acd8898d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ All notable changes to this project will be documented in this file. ### Added - DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight` - Support for I2C over Serial (#22444) +- Support KNX for scripts (#22429) +- Support deep sleep (standby) for VL53L0X (#22441) ### Breaking Changed @@ -15,9 +17,11 @@ All notable changes to this project will be documented in this file. - SGP4X ready for virtual I2C (#22427) - SCD40 reduce logging levels (#22443) - SCD40 ready for virtual I2C (#22443) +- Unit (k)VAr(h) to (k)var(h) (#22435) ### Fixed - ESP32-S3 UART output mode for Tx (#22426) +- Mitsubishi Electric HVAC Standby Stage for MiElHVAC (#22430) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 32a6d4e42..350c84c83 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -123,7 +123,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI command `DaliTarget` to set light control broadcast, group number or gear number - DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight` - DALI inverted signal configuration using GPIO DALI RX_i/TX_i -- Support for I2C over Serial [#224444](https://github.com/arendst/Tasmota/issues/224444) +- Support for I2C over Serial [#22444](https://github.com/arendst/Tasmota/issues/22444) +- Support KNX for scripts [#22429](https://github.com/arendst/Tasmota/issues/22429) +- Support deep sleep (standby) for VL53L0X [#22441](https://github.com/arendst/Tasmota/issues/22441) - Support for Shelly DALI Dimmer Gen3 - Support for HLK-LD2410S 24GHz smart wave motion sensor [#22253](https://github.com/arendst/Tasmota/issues/22253) - Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) @@ -141,6 +143,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Changed - ESP32 Platform from 2024.09.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241030 and IDF to 5.3.1.241024 [#22384](https://github.com/arendst/Tasmota/issues/22384) - ESP32 LVGL library from v9.2.0 to v9.2.2 [#22385](https://github.com/arendst/Tasmota/issues/22385) +- Unit (k)VAr(h) to (k)var(h) [#22435](https://github.com/arendst/Tasmota/issues/22435) - AHT1X/AHT2X/AHT3X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) - SGP4X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) - SCD40 reduce logging levels [#22443](https://github.com/arendst/Tasmota/issues/22443) @@ -153,6 +156,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Fixed - Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) +- Mitsubishi Electric HVAC Standby Stage for MiElHVAC [#22430](https://github.com/arendst/Tasmota/issues/22430) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 [#22367](https://github.com/arendst/Tasmota/issues/22367) - ESP32 Arduino Core IPv6 zones used by Matter [#22378](https://github.com/arendst/Tasmota/issues/22378) From a35bb5a5c9714b9828c73b2e3529280ecee24923 Mon Sep 17 00:00:00 2001 From: vtHydroponics <132159689+vtHydroponics@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:45:37 -0500 Subject: [PATCH 090/205] MS5837 functionality with BMP280 optional dependency (#22376) * Finalized gain/integration adjustment trees * Fixed the bugs * works but polishing code * need to debug pressure in bmp * updated temp to change via setoption8 command from tasmota * sensor table working, value reporting working, need to update dependency on sensor duality * working * updated file name for ms5837 xsns file * final working with renamed for current updates (128->116) * resolved PR comments for extra spaces, xi2c_96 * removed extra spaces, added unit for inches across languages * added "Water depth" for languages * removed inches as a unit from language files * switched to centimeter units for SI consistency in Tasmota * all variables showing in console and table; need to adjust offsets * cm conversion properly reporting * Sensor116 in console calibrates the sensor's pressure_offset variable * removed pressure offset debugging lines * removed unecessary commented items from old code --- .../Adafruit_TSL2591.h | 4 +- .../BlueRobotics_MS5837_Library/MS5837.cpp | 258 ++++++++++++++++++ .../BlueRobotics_MS5837_Library/MS5837.h | 113 ++++++++ tasmota/include/i18n.h | 2 + tasmota/include/tasmota_configurations.h | 1 + .../include/tasmota_configurations_ESP32.h | 2 + tasmota/language/af_AF.h | 3 +- tasmota/language/bg_BG.h | 1 + tasmota/language/ca_AD.h | 1 + tasmota/language/cs_CZ.h | 1 + tasmota/language/de_DE.h | 1 + tasmota/language/el_GR.h | 1 + tasmota/language/en_GB.h | 1 + tasmota/language/es_ES.h | 1 + tasmota/language/fr_FR.h | 1 + tasmota/language/fy_NL.h | 1 + tasmota/language/he_HE.h | 1 + tasmota/language/hu_HU.h | 1 + tasmota/language/it_IT.h | 1 + tasmota/language/ko_KO.h | 1 + tasmota/language/nl_NL.h | 1 + tasmota/language/pl_PL.h | 1 + tasmota/language/pt_BR.h | 1 + tasmota/language/pt_PT.h | 1 + tasmota/language/ro_RO.h | 1 + tasmota/language/ru_RU.h | 1 + tasmota/language/sk_SK.h | 1 + tasmota/language/sv_SE.h | 1 + tasmota/language/tr_TR.h | 1 + tasmota/language/uk_UA.h | 1 + tasmota/language/vi_VN.h | 1 + tasmota/language/zh_CN.h | 1 + tasmota/language/zh_TW.h | 1 + tasmota/my_user_config.h | 1 + tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino | 1 - .../tasmota_xsns_sensor/xsns_116_ms5837.ino | 148 ++++++++++ 36 files changed, 555 insertions(+), 4 deletions(-) create mode 100644 lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp create mode 100644 lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.h create mode 100644 tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino diff --git a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.h b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.h index bb4f846e5..2ae83f8d8 100644 --- a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.h +++ b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.h @@ -1,6 +1,6 @@ /**************************************************************************/ -/*! - @file Adafruit_TSL2591.h +/*! + @file Adafruit_TSL2591.h @author KT0WN (adafruit.com) This is a library for the Adafruit TSL2591 breakout board diff --git a/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp new file mode 100644 index 000000000..b93f2656a --- /dev/null +++ b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp @@ -0,0 +1,258 @@ +#include "MS5837.h" +#include + +const uint8_t MS5837_ADDR = 0x76; +const uint8_t MS5837_RESET = 0x1E; +const uint8_t MS5837_ADC_READ = 0x00; +const uint8_t MS5837_PROM_READ = 0xA0; +const uint8_t MS5837_CONVERT_D1_8192 = 0x4A; +const uint8_t MS5837_CONVERT_D2_8192 = 0x5A; + +const float MS5837::Pa = 100.0f; +const float MS5837::bar = 0.001f; +const float MS5837::mbar = 1.0f; + +const uint8_t MS5837::MS5837_30BA = 0; +const uint8_t MS5837::MS5837_02BA = 1; +const uint8_t MS5837::MS5837_UNRECOGNISED = 255; + +const uint8_t MS5837_02BA01 = 0x00; // Sensor version: From MS5837_02BA datasheet Version PROM Word 0 +const uint8_t MS5837_02BA21 = 0x15; // Sensor version: From MS5837_02BA datasheet Version PROM Word 0 +const uint8_t MS5837_30BA26 = 0x1A; // Sensor version: From MS5837_30BA datasheet Version PROM Word 0 + +MS5837::MS5837() { + fluidDensity = 1029; +} + +bool MS5837::begin(TwoWire &wirePort) { + return (init(wirePort)); +} + +bool MS5837::init(TwoWire &wirePort) { + _i2cPort = &wirePort; //Grab which port the user wants us to use + + // Reset the MS5837, per datasheet + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_RESET); + _i2cPort->endTransmission(); + + // Wait for reset to complete + delay(10); + + // Read calibration values and CRC + for ( uint8_t i = 0 ; i < 7 ; i++ ) { + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_PROM_READ+i*2); + _i2cPort->endTransmission(); + + _i2cPort->requestFrom(MS5837_ADDR,2); + C[i] = (_i2cPort->read() << 8) | _i2cPort->read(); + } + + // Verify that data is correct with CRC + uint8_t crcRead = C[0] >> 12; + uint8_t crcCalculated = crc4(C); + + if ( crcCalculated != crcRead ) { + return false; // CRC fail + } + + uint8_t version = (C[0] >> 5) & 0x7F; // Extract the sensor version from PROM Word 0 + + // Set _model according to the sensor version + if (version == MS5837_02BA01) + { + _model = MS5837_02BA; + } + else if (version == MS5837_02BA21) + { + _model = MS5837_02BA; + } + else if (version == MS5837_30BA26) + { + _model = MS5837_30BA; + } + else + { + _model = MS5837_UNRECOGNISED; + } + // The sensor has passed the CRC check, so we should return true even if + // the sensor version is unrecognised. + // (The MS5637 has the same address as the MS5837 and will also pass the CRC check) + // (but will hopefully be unrecognised.) + return true; +} + +void MS5837::setModel(uint8_t model) { + _model = model; +} + +uint8_t MS5837::getModel() { + return (_model); +} + +void MS5837::setFluidDensity(float density) { + fluidDensity = density; +} + +void MS5837::read() { + //Check that _i2cPort is not NULL (i.e. has the user forgoten to call .init or .begin?) + if (_i2cPort == NULL) + { + return; + } + + // Request D1 conversion + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_CONVERT_D1_8192); + _i2cPort->endTransmission(); + + delay(20); // Max conversion time per datasheet + + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_ADC_READ); + _i2cPort->endTransmission(); + + _i2cPort->requestFrom(MS5837_ADDR,3); + D1_pres = 0; + D1_pres = _i2cPort->read(); + D1_pres = (D1_pres << 8) | _i2cPort->read(); + D1_pres = (D1_pres << 8) | _i2cPort->read(); + + // Request D2 conversion + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_CONVERT_D2_8192); + _i2cPort->endTransmission(); + + delay(20); // Max conversion time per datasheet + + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_ADC_READ); + _i2cPort->endTransmission(); + + _i2cPort->requestFrom(MS5837_ADDR,3); + D2_temp = 0; + D2_temp = _i2cPort->read(); + D2_temp = (D2_temp << 8) | _i2cPort->read(); + D2_temp = (D2_temp << 8) | _i2cPort->read(); + + calculate(); +} + +void MS5837::calculate() { + // Given C1-C6 and D1, D2, calculated TEMP and P + // Do conversion first and then second order temp compensation + + int32_t dT = 0; + int64_t SENS = 0; + int64_t OFF = 0; + int32_t SENSi = 0; + int32_t OFFi = 0; + int32_t Ti = 0; + int64_t OFF2 = 0; + int64_t SENS2 = 0; + + // Terms called + dT = D2_temp-uint32_t(C[5])*256l; + if ( _model == MS5837_02BA ) { + SENS = int64_t(C[1])*65536l+(int64_t(C[3])*dT)/128l; + OFF = int64_t(C[2])*131072l+(int64_t(C[4])*dT)/64l; + P = (D1_pres*SENS/(2097152l)-OFF)/(32768l); + } else { + SENS = int64_t(C[1])*32768l+(int64_t(C[3])*dT)/256l; + OFF = int64_t(C[2])*65536l+(int64_t(C[4])*dT)/128l; + P = (D1_pres*SENS/(2097152l)-OFF)/(8192l); + } + + // Temp conversion + TEMP = 2000l+int64_t(dT)*C[6]/8388608LL; + + //Second order compensation + if ( _model == MS5837_02BA ) { + if((TEMP/100)<20){ //Low temp + Ti = (11*int64_t(dT)*int64_t(dT))/(34359738368LL); + OFFi = (31*(TEMP-2000)*(TEMP-2000))/8; + SENSi = (63*(TEMP-2000)*(TEMP-2000))/32; + } + } else { + if((TEMP/100)<20){ //Low temp + Ti = (3*int64_t(dT)*int64_t(dT))/(8589934592LL); + OFFi = (3*(TEMP-2000)*(TEMP-2000))/2; + SENSi = (5*(TEMP-2000)*(TEMP-2000))/8; + if((TEMP/100)<-15){ //Very low temp + OFFi = OFFi+7*(TEMP+1500l)*(TEMP+1500l); + SENSi = SENSi+4*(TEMP+1500l)*(TEMP+1500l); + } + } + else if((TEMP/100)>=20){ //High temp + Ti = 2*(dT*dT)/(137438953472LL); + OFFi = (1*(TEMP-2000)*(TEMP-2000))/16; + SENSi = 0; + } + } + + OFF2 = OFF-OFFi; //Calculate pressure and temp second order + SENS2 = SENS-SENSi; + + TEMP = (TEMP-Ti); + + if ( _model == MS5837_02BA ) { + P = (((D1_pres*SENS2)/2097152l-OFF2)/32768l); + } else { + P = (((D1_pres*SENS2)/2097152l-OFF2)/8192l); + } +} + +float MS5837::pressure(float conversion) { + if ( _model == MS5837_02BA ) { + return P*conversion/100.0f; + } + else { + return P*conversion/10.0f; + } +} + +float MS5837::temperature() { + return TEMP/100.0f; +} + +// The pressure sensor measures absolute pressure, so it will measure the atmospheric pressure + water pressure +// We subtract the atmospheric pressure to calculate the depth with only the water pressure +// The average atmospheric pressure of 101300 pascal is used for the calcuation, but atmospheric pressure varies +// If the atmospheric pressure is not 101300 at the time of reading, the depth reported will be offset +// In order to calculate the correct depth, the actual atmospheric pressure should be measured once in air, and +// that value should subtracted for subsequent depth calculations. +float MS5837::depth() { + return (pressure(MS5837::Pa)-101300)/(fluidDensity*9.80665f); +} + +float MS5837::altitude() { + return (1-pow((pressure()/1013.25f),.190284f))*145366.45f*.3048f; +} + + +uint8_t MS5837::crc4(uint16_t n_prom[]) { + uint16_t n_rem = 0; + + n_prom[0] = ((n_prom[0]) & 0x0FFF); + n_prom[7] = 0; + + for ( uint8_t i = 0 ; i < 16; i++ ) { + if ( i%2 == 1 ) { + n_rem ^= (uint16_t)((n_prom[i>>1]) & 0x00FF); + } else { + n_rem ^= (uint16_t)(n_prom[i>>1] >> 8); + } + for ( uint8_t n_bit = 8 ; n_bit > 0 ; n_bit-- ) { + if ( n_rem & 0x8000 ) { + n_rem = (n_rem << 1) ^ 0x3000; + } else { + n_rem = (n_rem << 1); + } + } + } + + n_rem = ((n_rem >> 12) & 0x000F); + + return n_rem ^ 0x00; +} diff --git a/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.h b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.h new file mode 100644 index 000000000..8787de1b6 --- /dev/null +++ b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.h @@ -0,0 +1,113 @@ +/* Blue Robotics Arduino MS5837-30BA Pressure/Temperature Sensor Library +------------------------------------------------------------ + +Title: Blue Robotics Arduino MS5837-30BA Pressure/Temperature Sensor Library + +Description: This library provides utilities to communicate with and to +read data from the Measurement Specialties MS5837-30BA pressure/temperature +sensor. + +Authors: Rustom Jehangir, Blue Robotics Inc. + Adam Šimko, Blue Robotics Inc. + +------------------------------- +The MIT License (MIT) + +Copyright (c) 2015 Blue Robotics Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------*/ + +#ifndef MS5837_H_BLUEROBOTICS +#define MS5837_H_BLUEROBOTICS + +#include "Arduino.h" +#include + +class MS5837 { +public: + static const float Pa; + static const float bar; + static const float mbar; + + static const uint8_t MS5837_30BA; + static const uint8_t MS5837_02BA; + static const uint8_t MS5837_UNRECOGNISED; + + MS5837(); + + bool init(TwoWire &wirePort = Wire); + bool begin(TwoWire &wirePort = Wire); // Calls init() + + /** Set model of MS5837 sensor. Valid options are MS5837::MS5837_30BA (default) + * and MS5837::MS5837_02BA. + */ + void setModel(uint8_t model); + uint8_t getModel(); + + /** Provide the density of the working fluid in kg/m^3. Default is for + * seawater. Should be 997 for freshwater. + */ + void setFluidDensity(float density); + + /** The read from I2C takes up to 40 ms, so use sparingly is possible. + */ + void read(); + + /** Pressure returned in mbar or mbar*conversion rate. + */ + float pressure(float conversion = 1.0f); + + /** Temperature returned in deg C. + */ + float temperature(); + + /** Depth returned in meters (valid for operation in incompressible + * liquids only. Uses density that is set for fresh or seawater. + */ + float depth(); + + /** Altitude returned in meters (valid for operation in air only). + */ + float altitude(); + + uint8_t crc4(uint16_t n_prom[]); + +private: + + //This stores the requested i2c port + TwoWire * _i2cPort; + + uint16_t C[8]; + uint32_t D1_pres, D2_temp; + int32_t TEMP; + int32_t P; + uint8_t _model; + + float fluidDensity; + + /** Performs calculations per the sensor data sheet for conversion and + * second order compensation. + */ + void calculate(); + + //uint8_t crc4(uint16_t n_prom[]); +}; + +#endif diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h index b243f01e4..48d6d20ff 100644 --- a/tasmota/include/i18n.h +++ b/tasmota/include/i18n.h @@ -219,6 +219,7 @@ #define D_JSON_VERSION "Version" #define D_JSON_VOLTAGE "Voltage" #define D_JSON_VOLUME "Volume" +#define D_JSON_WATER_DEPTH "Water Depth" #define D_JSON_WEIGHT "Weight" #define D_JSON_WIFI "Wifi" #define D_JSON_WIFI_MODE "Mode" @@ -1001,6 +1002,7 @@ const char HTTP_SNS_MILLILITERS[] PROGMEM = "{s}%s " D_VOLUME "{ const char HTTP_SNS_GAS[] PROGMEM = "{s}%s " D_GAS "{m}%d " D_UNIT_PERCENT "LEL{e}"; const char HTTP_SNS_SOC[] PROGMEM = "{s}%s " D_SOC "{m}%d " D_UNIT_PERCENT "{e}"; const char HTTP_SNS_SOH[] PROGMEM = "{s}%s " D_SOH "{m}%d " D_UNIT_PERCENT "{e}"; +const char HTTP_SNS_WATER_DEPTH[] PROGMEM = "{s}%s " D_WATER_DEPTH "{m}%s " D_UNIT_CENTIMETER "{e}"; const char HTTP_SNS_STANDARD_CONCENTRATION[] PROGMEM = "{s}%s " D_STANDARD_CONCENTRATION " %s " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"; const char HTTP_SNS_ENVIRONMENTAL_CONCENTRATION[] PROGMEM = "{s}%s " D_ENVIRONMENTAL_CONCENTRATION " %s " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"; diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h index 7a1118b9c..287190c24 100644 --- a/tasmota/include/tasmota_configurations.h +++ b/tasmota/include/tasmota_configurations.h @@ -173,6 +173,7 @@ //#define USE_MAX17043 // [I2cDriver83] Enable MAX17043 fuel-gauge systems Lipo batteries sensor (I2C address 0x36) (+0k9 code) //#define USE_AMSX915 // [I2CDriver86] Enable AMS5915/AMS6915 pressure/temperature sensor (+1k2 code) //#define USE_SPL06_007 // [I2cDriver87] Enable SPL06_007 pressure and temperature sensor (I2C addresses 0x76) (+2k5 code) +//#define USE_MS5837 //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 4b89f545d..9a78a94b8 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -450,6 +450,7 @@ //#define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code) //#define USE_PMSA003I // [I2cDriver78] Enable PMSA003I Air Quality Sensor (I2C address 0x12) (+1k8 code) //#define USE_GDK101 // [I2cDriver79] Enable GDK101 sensor (I2C addresses 0x18 - 0x1B) (+1k2 code) +// #define USE_MS5837 //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) @@ -692,6 +693,7 @@ //#define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code) //#define USE_PMSA003I // [I2cDriver78] Enable PMSA003I Air Quality Sensor (I2C address 0x12) (+1k8 code) //#define USE_GDK101 // [I2cDriver79] Enable GDK101 sensor (I2C addresses 0x18 - 0x1B) (+1k2 code) +// #define USE_MS5837 //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 8efd1ff09..e863df45c 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Webbediener" #define D_SOC "Laai kondisie" #define D_SOH "Laai vermoeë" +#define D_WATER_DEPTH "Water diepte" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "WAARSKUWING Hierdie weergawe ondersteun nie aanhoudende instellings nie" @@ -1289,7 +1290,7 @@ #define D_MOVING_ENERGY_T "Moving target" #define D_STATIC_ENERGY_T "Static target" #define D_LD2410_PIN_STATE "Output pin state" -#define D_LD2410_LIGHT "Light sensor" +#define D_LD2410_LIGHT "Light sensor" // xsns_115_wooliis.ino #define D_IMPORT "Import" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index e633d6cbb..50560e359 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Уеб сървър" #define D_SOC "Съснояние на зареждане" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Дълбочина на водата" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ПРЕДУПРЕЖДЕНИЕ Тази версия не поддържа постоянни настройки" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index 54880bebe..93ce54f52 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Servidor Web" #define D_SOC "Estat de canvi" #define D_SOH "Estat de salut" +#define D_WATER_DEPTH "Profunditat de l'aigua" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "Avís : Aquesta versió no suporta configuració persistent" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index ae48211ef..cf3b917f0 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Web Server" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Hloubka vody" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "UPOZORNĚNÍ Tato verze nepodporuje trvalé nastavení" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index e186de688..a25a7030b 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Webserver" #define D_SOC "Ladestatus" #define D_SOH "Gesundheitsstatus" +#define D_WATER_DEPTH "Wassertiefe" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ACHTUNG: Diese Version unterstützt keine persistenten Einstellungen" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 782b1acb9..3194feeec 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Διακομιστής Web" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Βάθος νερού" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ΠΡΟΕΙΔΟΠΟΙΗΣΗ Αυτή η έκδοση δεν αποθηκεύει τις ρυθμίσεις" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index c66232eaa..9133db349 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Web Server" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Water Depth" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "WARNING This version does not support persistent settings" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index dba5a1d54..bcba22c7e 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Servidor Web" #define D_SOC "Estado de Carga" #define D_SOH "Estado de Salud" +#define D_WATER_DEPTH "Profundidad del agua" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "Cuidado, esta versión no guarda los cambios" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 2a0b293d9..1a9f67add 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Serveur web" #define D_SOC "État de la Charge" #define D_SOH "État de Santé" +#define D_WATER_DEPTH "Profondeur de l’eau" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ATTENTION Cette version ne gère pas les réglages persistants" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index b461da25f..ced0b6087 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Webserver" #define D_SOC "State of Charge" #define D_SOH "State of Charge" +#define D_WATER_DEPTH "Vattendjup" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "WARSKOGING Dizze ferzje bewarret gjin ynstellings" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index b501c6978..ed49d923a 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Web שרת" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "עומק המים" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "אזהרה גרסה זו אינה תומכת בהגדרות קבועות" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 8530e60c3..50bc0c9c7 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Webszerver" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Vízmélység" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "VIGYÁZZ! Ez a verzió nem támogat tartós beállításokat" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index d12030865..dd4d5a1f6 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Server web" #define D_SOC "Stato di carica" #define D_SOH "State di salute" +#define D_WATER_DEPTH "Profondità dell'acqua" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ATTENZIONE Questa versione non supporta il salvataggio delle impostazioni" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 4404b3b18..8c19dbffe 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "웹 서버" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "수심" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "경고: 이 버전은 영구 설정을 지원하지 않습니다" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 527389197..f3143e094 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Webserver" #define D_SOC "Laadtoestand" #define D_SOH "Gezondheid" +#define D_WATER_DEPTH "Diepte van het water" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "WAARSCHUWING Deze versie bewaart geen instellingen" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 2be37fe0b..94e6f1ab1 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Serwer Web" #define D_SOC "Stan naładowania" #define D_SOH "Kondycja" +#define D_WATER_DEPTH "Głębokość wody" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "UWAGA Ta wersja nie obsługuje zapisu ustawień" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 4327aec5b..186f156ad 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Servidor WEB" #define D_SOC "Estado de Carga" #define D_SOH "Estado de Saúde" +#define D_WATER_DEPTH "Profundidade da água" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "AVISO: esta versão não supporta configurações persistentes" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index f659ed236..e75bdc3c3 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Servidor WEB" #define D_SOC "Estado de Carga" #define D_SOH "Estado de Saúde" +#define D_WATER_DEPTH "Profundidade da água" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "AVISO esta versão não supporta configurações persistentes" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index d0be73bd4..982d7599f 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Server Web" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Adâncimea apei" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ATENȚIE Această versiune nu suportă setări permanente" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 8fb70f1e9..bf2148662 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -216,6 +216,7 @@ #define D_WEB_SERVER "Веб-сервер" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Глубина воды" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ПРЕДУПРЕЖДЕНИЕ Эта версия не поддерживает персистентные настройки" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 3bb13d21a..7e95c1680 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Web Server" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Hĺbka vody" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "UPOZORNENIE Táto verzia nepodporuje trvalé nastavenia" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 2c0ddedaa..c2988b36f 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Webbserver" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Vattendjup" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "VARNING Denna version supporterar inte beständiga inställningar" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 3c8a01f11..7880d2ce0 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Web Sunucusu" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Su derinliği" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "UYARI Bu versiyon ayarların kalıcı olarak kaydedilmesine olanak sağlamıyor" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 3ea86116f..42b14bec8 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Web сервер" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Глибина води" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ПОПЕРЕДЖЕННЯ! Ця версія не підтримує збереження налаштувань" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 5cc64f7f3..62762814a 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Máy chủ Web" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "Độ sâu nước" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "Cảnh báo phiên bản này không hỗ trợ các cài đặt vĩnh viễn" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 3f6742a79..28699b933 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "Web服务器" #define D_SOC "充电状态" #define D_SOH "充电健康" +#define D_WATER_DEPTH "水深" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "警告:精简固件不支持持久保存设置" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index dd6e80fcd..b65007bf0 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -215,6 +215,7 @@ #define D_WEB_SERVER "網頁伺服器" #define D_SOC "State of Charge" #define D_SOH "State of Health" +#define D_WATER_DEPTH "水深" // tasmota.ino #define D_WARNING_MINIMAL_VERSION "警告,這個版本並不支援將設定永久的儲存!" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 39a78820b..69bad90bd 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -750,6 +750,7 @@ // #define USE_AMSX915 // [I2CDriver86] Enable AMS5915/AMS6915 pressure/temperature sensor (+1k2 code) // #define USE_SPL06_007 // [I2cDriver87] Enable SPL06_007 pressure and temperature sensor (I2C addresses 0x76) (+2k5 code) // #define USE_QMP6988 // [I2cDriver88] Enable QMP6988 pressure and temperature sensor (I2C address 0x56 or 0x70) (+2k9 code) +// #define USE_MS5837 // #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC - used by Ulanzi TC001 (I2C address 0x68) (+1k2 code) diff --git a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino index 19144d2d9..ecdb60886 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino @@ -16,7 +16,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - #ifdef USE_I2C #ifdef USE_BMP /*********************************************************************************************\ diff --git a/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino b/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino new file mode 100644 index 000000000..9d0211f4b --- /dev/null +++ b/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino @@ -0,0 +1,148 @@ +/* + xsns_116_ms5837.ino - BlueRobotics MS5837 pressure and temperature sensor support for Tasmota + + Copyright (C) 2022 Theo Arends, Stefan Tibus + + 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_I2C +#ifdef USE_MS5837 + +#define MS5837_ADDR 0x76 + +#define XSNS_116 116 +#define XI2C_91 91 // See I2CDEVICES.md +/*********************************************************************************************\ + * BlueRobotics Pressure Sensor + * + * This driver supports the following sensors: + * - BlueRobotics MS5837 +\*********************************************************************************************/ + +#include +#include + +MS5837 sensor_ms5837; + +uint8_t ms5837Start = 0; +float pressure_offset = 2.85f; + +/********************************************************************************************/ + +void MS5837init(void) { + + if (I2cSetDevice(0x76)) { + TwoWire& myWire = I2cGetWire(); + + if(sensor_ms5837.init(myWire)) { + sensor_ms5837.setModel(sensor_ms5837.MS5837_02BA); + sensor_ms5837.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater) + ms5837Start = 1; + I2cSetActiveFound(MS5837_ADDR, "MS5837"); + } + } +} + +#ifdef USE_WEBSERVER +const char name_str[] PROGMEM = "MS5837"; +#endif // USE_WEBSERVER + +void MS5837Show(bool json) { + float ms5837Temp; + float ms5837Pres; + float pressure_delta; + float cm_water; + char temperature_str[8]; + char pressure_str[8]; + char cmWater_str[8]; + + if (I2cEnabled(XI2C_91)) { + sensor_ms5837.read(); + ms5837Temp = ConvertTemp(sensor_ms5837.temperature()); + ms5837Pres = ConvertPressure(sensor_ms5837.pressure() + pressure_offset); + ext_snprintf_P(temperature_str, sizeof(temperature_str), PSTR("%1_f"), &ms5837Temp); + ext_snprintf_P(pressure_str, sizeof(pressure_str), PSTR("%1_f"), &ms5837Pres); + if (json) { + ResponseAppend_P(PSTR(",\"MS5837\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), temperature_str, pressure_str); + } + if (I2cEnabled(XI2C_10)) { + pressure_delta = (sensor_ms5837.pressure() + pressure_offset) - bmp_sensors[0].bmp_pressure; + cm_water = pressure_delta*0.401463078662f*2.54f; // changes from inches to cm after read using 2.54cm/in conversion + ext_snprintf_P(cmWater_str, sizeof(cmWater_str), PSTR("%1_f"), &cm_water); + if (json) { + ResponseAppend_P(PSTR(",\"" D_JSON_WATER_DEPTH "\":%s"),cmWater_str); + } + } + if (json) { + ResponseAppend_P(PSTR("}")); + +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_F_TEMP, name_str, Settings->flag2.temperature_resolution, &ms5837Temp, TempUnit()); + WSContentSend_PD(HTTP_SNS_PRESSURE, name_str, pressure_str, PressureUnit().c_str()); + if (I2cEnabled(XI2C_10)) { + WSContentSend_PD(HTTP_SNS_WATER_DEPTH, name_str, &cmWater_str); + } +#endif // USE_WEBSERVER + } + } +} + +bool ms5837CommandSensor() { + bool serviced = true; + switch (XdrvMailbox.payload) { + case 0: + MS5837Show(0); + pressure_offset = bmp_sensors[0].bmp_pressure - sensor_ms5837.pressure(); + break; + } + return serviced; +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns116(uint32_t function) { + if (!I2cEnabled(XI2C_91)) { return false; } + + bool result = false; + //I2cScan(); + + if (FUNC_INIT == function) { + MS5837init(); + } + else if (ms5837Start) { + switch (function) { + case FUNC_COMMAND_SENSOR: + if (XSNS_116 == XdrvMailbox.index) { + result = ms5837CommandSensor(); + } + break; + case FUNC_JSON_APPEND: + MS5837Show(1); + break; + #ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + MS5837Show(0); + break; + #endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_MS5837 +#endif // USE_I2C \ No newline at end of file From df293dad82ca1b55c34619f2a6996081cbb5ee96 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Nov 2024 18:16:26 +0100 Subject: [PATCH 091/205] Add support MS5837 --- CHANGELOG.md | 1 + I2CDEVICES.md | 1 + RELEASENOTES.md | 1 + tasmota/include/tasmota_configurations.h | 2 +- .../include/tasmota_configurations_ESP32.h | 4 +- tasmota/my_user_config.h | 2 +- .../tasmota_xsns_sensor/xsns_116_ms5837.ino | 45 +++++++++++-------- 7 files changed, 33 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acd8898d5..20d6c54e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - Support for I2C over Serial (#22444) - Support KNX for scripts (#22429) - Support deep sleep (standby) for VL53L0X (#22441) +- Support for MS5837 pressure and temperature sensor (#22376) ### Breaking Changed diff --git a/I2CDEVICES.md b/I2CDEVICES.md index d873bbd59..79a2bf81a 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -128,5 +128,6 @@ Index | Define | Driver | Device | Address(es) | Bus2 | Descrip 88 | USE_QMP6988 | xsns_28 | QMP6988 | 0x56, 0x70 | Yes | Pressure and temperature sensor 89 | USE_HX711_M5SCALES | xsns_34 | M5SCALES | 0x26 | Yes | M5Unit (Mini)Scales(HX711 STM32) U177 90 | USE_RX8010 | xdrv_56 | RX8010 | 0x32 | Yes | RX8010 RTC from IOTTIMER + 91 | USE_MS5837 | xsns_116 | MS5837 | 0x76 | | Pressure and temperature sensor NOTE: Bus2 supported on ESP32 only. diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 350c84c83..d8ced5db0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -129,6 +129,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Support for Shelly DALI Dimmer Gen3 - Support for HLK-LD2410S 24GHz smart wave motion sensor [#22253](https://github.com/arendst/Tasmota/issues/22253) - Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) +- Support for MS5837 pressure and temperature sensor [#22376](https://github.com/arendst/Tasmota/issues/22376) - HLK-LD2410 Engineering mode [#21880](https://github.com/arendst/Tasmota/issues/21880) - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h index 287190c24..36721339b 100644 --- a/tasmota/include/tasmota_configurations.h +++ b/tasmota/include/tasmota_configurations.h @@ -173,7 +173,7 @@ //#define USE_MAX17043 // [I2cDriver83] Enable MAX17043 fuel-gauge systems Lipo batteries sensor (I2C address 0x36) (+0k9 code) //#define USE_AMSX915 // [I2CDriver86] Enable AMS5915/AMS6915 pressure/temperature sensor (+1k2 code) //#define USE_SPL06_007 // [I2cDriver87] Enable SPL06_007 pressure and temperature sensor (I2C addresses 0x76) (+2k5 code) -//#define USE_MS5837 +//#define USE_MS5837 // [I2cDriver91] Enable MS5837 sensor (I2C address 0x76) (+2k7 code) //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 9a78a94b8..82524e9f5 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -450,7 +450,7 @@ //#define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code) //#define USE_PMSA003I // [I2cDriver78] Enable PMSA003I Air Quality Sensor (I2C address 0x12) (+1k8 code) //#define USE_GDK101 // [I2cDriver79] Enable GDK101 sensor (I2C addresses 0x18 - 0x1B) (+1k2 code) -// #define USE_MS5837 +//#define USE_MS5837 // [I2cDriver91] Enable MS5837 sensor (I2C address 0x76) (+2k7 code) //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) @@ -693,7 +693,7 @@ //#define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code) //#define USE_PMSA003I // [I2cDriver78] Enable PMSA003I Air Quality Sensor (I2C address 0x12) (+1k8 code) //#define USE_GDK101 // [I2cDriver79] Enable GDK101 sensor (I2C addresses 0x18 - 0x1B) (+1k2 code) -// #define USE_MS5837 +//#define USE_MS5837 // [I2cDriver91] Enable MS5837 sensor (I2C address 0x76) (+2k7 code) //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 69bad90bd..c28e33ca3 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -750,7 +750,7 @@ // #define USE_AMSX915 // [I2CDriver86] Enable AMS5915/AMS6915 pressure/temperature sensor (+1k2 code) // #define USE_SPL06_007 // [I2cDriver87] Enable SPL06_007 pressure and temperature sensor (I2C addresses 0x76) (+2k5 code) // #define USE_QMP6988 // [I2cDriver88] Enable QMP6988 pressure and temperature sensor (I2C address 0x56 or 0x70) (+2k9 code) -// #define USE_MS5837 +// #define USE_MS5837 // [I2cDriver91] Enable MS5837 sensor (I2C address 0x76) (+2k7 code) // #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC - used by Ulanzi TC001 (I2C address 0x68) (+1k2 code) diff --git a/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino b/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino index 9d0211f4b..49bc8db10 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino @@ -19,25 +19,27 @@ #ifdef USE_I2C #ifdef USE_MS5837 - -#define MS5837_ADDR 0x76 - -#define XSNS_116 116 -#define XI2C_91 91 // See I2CDEVICES.md /*********************************************************************************************\ * BlueRobotics Pressure Sensor * * This driver supports the following sensors: * - BlueRobotics MS5837 + * + * I2C Address: 0x76 \*********************************************************************************************/ +#define XSNS_116 116 +#define XI2C_91 91 // See I2CDEVICES.md + +#define MS5837_ADDR 0x76 + #include #include -MS5837 sensor_ms5837; +MS5837 ms5837_sensor; -uint8_t ms5837Start = 0; -float pressure_offset = 2.85f; +bool ms5837_start = false; +float ms5837_pressure_offset = 2.85f; /********************************************************************************************/ @@ -46,10 +48,10 @@ void MS5837init(void) { if (I2cSetDevice(0x76)) { TwoWire& myWire = I2cGetWire(); - if(sensor_ms5837.init(myWire)) { - sensor_ms5837.setModel(sensor_ms5837.MS5837_02BA); - sensor_ms5837.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater) - ms5837Start = 1; + if(ms5837_sensor.init(myWire)) { + ms5837_sensor.setModel(ms5837_sensor.MS5837_02BA); + ms5837_sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater) + ms5837_start = true; I2cSetActiveFound(MS5837_ADDR, "MS5837"); } } @@ -69,22 +71,24 @@ void MS5837Show(bool json) { char cmWater_str[8]; if (I2cEnabled(XI2C_91)) { - sensor_ms5837.read(); - ms5837Temp = ConvertTemp(sensor_ms5837.temperature()); - ms5837Pres = ConvertPressure(sensor_ms5837.pressure() + pressure_offset); + ms5837_sensor.read(); + ms5837Temp = ConvertTemp(ms5837_sensor.temperature()); + ms5837Pres = ConvertPressure(ms5837_sensor.pressure() + ms5837_pressure_offset); ext_snprintf_P(temperature_str, sizeof(temperature_str), PSTR("%1_f"), &ms5837Temp); ext_snprintf_P(pressure_str, sizeof(pressure_str), PSTR("%1_f"), &ms5837Pres); if (json) { ResponseAppend_P(PSTR(",\"MS5837\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), temperature_str, pressure_str); } +#ifdef USE_BMP if (I2cEnabled(XI2C_10)) { - pressure_delta = (sensor_ms5837.pressure() + pressure_offset) - bmp_sensors[0].bmp_pressure; + pressure_delta = (ms5837_sensor.pressure() + ms5837_pressure_offset) - bmp_sensors[0].bmp_pressure; cm_water = pressure_delta*0.401463078662f*2.54f; // changes from inches to cm after read using 2.54cm/in conversion ext_snprintf_P(cmWater_str, sizeof(cmWater_str), PSTR("%1_f"), &cm_water); if (json) { ResponseAppend_P(PSTR(",\"" D_JSON_WATER_DEPTH "\":%s"),cmWater_str); } } +#endif // USE_BMP if (json) { ResponseAppend_P(PSTR("}")); @@ -92,9 +96,11 @@ void MS5837Show(bool json) { } else { WSContentSend_PD(HTTP_SNS_F_TEMP, name_str, Settings->flag2.temperature_resolution, &ms5837Temp, TempUnit()); WSContentSend_PD(HTTP_SNS_PRESSURE, name_str, pressure_str, PressureUnit().c_str()); +#ifdef USE_BMP if (I2cEnabled(XI2C_10)) { WSContentSend_PD(HTTP_SNS_WATER_DEPTH, name_str, &cmWater_str); } +#endif // USE_BMP #endif // USE_WEBSERVER } } @@ -105,7 +111,9 @@ bool ms5837CommandSensor() { switch (XdrvMailbox.payload) { case 0: MS5837Show(0); - pressure_offset = bmp_sensors[0].bmp_pressure - sensor_ms5837.pressure(); +#ifdef USE_BMP + ms5837_pressure_offset = bmp_sensors[0].bmp_pressure - ms5837_sensor.pressure(); +#endif // USE_BMP break; } return serviced; @@ -119,12 +127,11 @@ bool Xsns116(uint32_t function) { if (!I2cEnabled(XI2C_91)) { return false; } bool result = false; - //I2cScan(); if (FUNC_INIT == function) { MS5837init(); } - else if (ms5837Start) { + else if (ms5837_start) { switch (function) { case FUNC_COMMAND_SENSOR: if (XSNS_116 == XdrvMailbox.index) { From 7c82d3a7ae1bc1c3eeaf0cbccc655bd6654b1168 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:22:53 +0100 Subject: [PATCH 092/205] Berry add I2C read16/write16 supporting Little Endian (#22448) --- CHANGELOG.md | 1 + .../berry_tasmota/src/embedded/i2c_driver.be | 14 + .../src/solidify/solidified_i2c_driver.h | 594 +++++++++++------- 3 files changed, 366 insertions(+), 243 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d6c54e9..47a3d7f5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - Support KNX for scripts (#22429) - Support deep sleep (standby) for VL53L0X (#22441) - Support for MS5837 pressure and temperature sensor (#22376) +- Berry add I2C read16/write16 supporting Little Endian ### Breaking Changed diff --git a/lib/libesp32/berry_tasmota/src/embedded/i2c_driver.be b/lib/libesp32/berry_tasmota/src/embedded/i2c_driver.be index 97cd50a3b..540dcc169 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/i2c_driver.be +++ b/lib/libesp32/berry_tasmota/src/embedded/i2c_driver.be @@ -56,6 +56,15 @@ class I2C_Driver def write8(reg, val) return self.wire.write(self.addr, reg, val, 1) end + #- write register with 16 bits value -# + def write16(reg, val) + return self.wire.write(self.addr, reg, val, 2) + end + #- write register with 16 bits value, Little Endian -# + def write16LE(reg, val) + val = ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8) + return self.write16(reg, val) + end # Set or clear a specific bit in a register # write_bit(reg:int, bit:int, state:bool) -> nil @@ -94,6 +103,11 @@ class I2C_Driver var buf = self.wire.read_bytes(self.addr, reg, 2) return (buf[0] << 8) + buf[1] end + # read 16 bits Little Endian + def read16LE(reg) + var buf = self.wire.read_bytes(self.addr, reg, 2) + return (buf[1] << 8) + buf[0] + end # read 24 bits def read24(reg) var buf = self.wire.read_bytes(self.addr, reg, 3) diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_i2c_driver.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_i2c_driver.h index 1c0147425..cc8fcf12b 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_i2c_driver.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_i2c_driver.h @@ -3,81 +3,33 @@ * Generated code, don't edit * \********************************************************************/ #include "be_constobj.h" -// compact class 'I2C_Driver' ktab size: 19, total: 60 (saved 328 bytes) -static const bvalue be_ktab_class_I2C_Driver[19] = { - /* K0 */ be_const_int(0), - /* K1 */ be_const_int(1), - /* K2 */ be_nested_str(write8), - /* K3 */ be_nested_str(read8), - /* K4 */ be_nested_str(wire), - /* K5 */ be_nested_str(read_bytes), - /* K6 */ be_nested_str(addr), - /* K7 */ be_const_int(2), - /* K8 */ be_const_int(3), - /* K9 */ be_nested_str(tasmota), - /* K10 */ be_nested_str(i2c_enabled), - /* K11 */ be_nested_str(wire_scan), - /* K12 */ be_nested_str(function), - /* K13 */ be_nested_str(name), - /* K14 */ be_nested_str(I2C_X3A), - /* K15 */ be_nested_str(detected_X20on_X20bus), - /* K16 */ be_nested_str(bus), - /* K17 */ be_nested_str(write), +// compact class 'I2C_Driver' ktab size: 20, total: 71 (saved 408 bytes) +static const bvalue be_ktab_class_I2C_Driver[20] = { + /* K0 */ be_nested_str(wire), + /* K1 */ be_nested_str(read_bytes), + /* K2 */ be_nested_str(addr), + /* K3 */ be_const_int(0), + /* K4 */ be_const_int(1), + /* K5 */ be_const_int(2), + /* K6 */ be_const_int(3), + /* K7 */ be_nested_str(tasmota), + /* K8 */ be_nested_str(i2c_enabled), + /* K9 */ be_nested_str(wire_scan), + /* K10 */ be_nested_str(function), + /* K11 */ be_nested_str(name), + /* K12 */ be_nested_str(I2C_X3A), + /* K13 */ be_nested_str(detected_X20on_X20bus), + /* K14 */ be_nested_str(bus), + /* K15 */ be_nested_str(write8), + /* K16 */ be_nested_str(read8), + /* K17 */ be_nested_str(write16), /* K18 */ be_nested_str(read), + /* K19 */ be_nested_str(write), }; extern const bclass be_class_I2C_Driver; -/******************************************************************** -** Solidified function: write_bit -********************************************************************/ -be_local_closure(class_I2C_Driver_write_bit, /* name */ - be_nested_proto( - 11, /* nstack */ - 4, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_I2C_Driver, /* shared constants */ - &be_const_str_write_bit, - &be_const_str_solidified, - ( &(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: read32 ********************************************************************/ @@ -95,24 +47,24 @@ be_local_closure(class_I2C_Driver_read32, /* name */ &be_const_str_read32, &be_const_str_solidified, ( &(const binstruction[20]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 - 0x8C080505, // 0001 GETMET R2 R2 K5 - 0x88100106, // 0002 GETMBR R4 R0 K6 + 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 - 0x940C0500, // 0006 GETIDX R3 R2 K0 + 0x940C0503, // 0006 GETIDX R3 R2 K3 0x54120017, // 0007 LDINT R4 24 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100501, // 0009 GETIDX R4 R2 K1 + 0x94100504, // 0009 GETIDX R4 R2 K4 0x5416000F, // 000A LDINT R5 16 0x38100805, // 000B SHL R4 R4 R5 0x000C0604, // 000C ADD R3 R3 R4 - 0x94100507, // 000D GETIDX R4 R2 K7 + 0x94100505, // 000D GETIDX R4 R2 K5 0x54160007, // 000E LDINT R5 8 0x38100805, // 000F SHL R4 R4 R5 0x000C0604, // 0010 ADD R3 R3 R4 - 0x94100508, // 0011 GETIDX R4 R2 K8 + 0x94100506, // 0011 GETIDX R4 R2 K6 0x000C0604, // 0012 ADD R3 R3 R4 0x80040600, // 0013 RET 1 R3 }) @@ -121,115 +73,6 @@ be_local_closure(class_I2C_Driver_read32, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: read13 -********************************************************************/ -be_local_closure(class_I2C_Driver_read13, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_I2C_Driver, /* shared constants */ - &be_const_str_read13, - &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 - 0x8C080505, // 0001 GETMET R2 R2 K5 - 0x88100106, // 0002 GETMBR R4 R0 K6 - 0x5C140200, // 0003 MOVE R5 R1 - 0x58180007, // 0004 LDCONST R6 K7 - 0x7C080800, // 0005 CALL R2 4 - 0x940C0500, // 0006 GETIDX R3 R2 K0 - 0x54120004, // 0007 LDINT R4 5 - 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100501, // 0009 GETIDX R4 R2 K1 - 0x000C0604, // 000A ADD R3 R3 R4 - 0x80040600, // 000B RET 1 R3 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read24 -********************************************************************/ -be_local_closure(class_I2C_Driver_read24, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_I2C_Driver, /* shared constants */ - &be_const_str_read24, - &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 - 0x8C080505, // 0001 GETMET R2 R2 K5 - 0x88100106, // 0002 GETMBR R4 R0 K6 - 0x5C140200, // 0003 MOVE R5 R1 - 0x58180008, // 0004 LDCONST R6 K8 - 0x7C080800, // 0005 CALL R2 4 - 0x940C0500, // 0006 GETIDX R3 R2 K0 - 0x5412000F, // 0007 LDINT R4 16 - 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100501, // 0009 GETIDX R4 R2 K1 - 0x54160007, // 000A LDINT R5 8 - 0x38100805, // 000B SHL R4 R4 R5 - 0x000C0604, // 000C ADD R3 R3 R4 - 0x94100507, // 000D GETIDX R4 R2 K7 - 0x000C0604, // 000E ADD R3 R3 R4 - 0x80040600, // 000F RET 1 R3 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read14 -********************************************************************/ -be_local_closure(class_I2C_Driver_read14, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_I2C_Driver, /* shared constants */ - &be_const_str_read14, - &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 - 0x8C080505, // 0001 GETMET R2 R2 K5 - 0x88100106, // 0002 GETMBR R4 R0 K6 - 0x5C140200, // 0003 MOVE R5 R1 - 0x58180007, // 0004 LDCONST R6 K7 - 0x7C080800, // 0005 CALL R2 4 - 0x940C0500, // 0006 GETIDX R3 R2 K0 - 0x54120005, // 0007 LDINT R4 6 - 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100501, // 0009 GETIDX R4 R2 K1 - 0x000C0604, // 000A ADD R3 R3 R4 - 0x80040600, // 000B RET 1 R3 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: init ********************************************************************/ @@ -250,45 +93,45 @@ be_local_closure(class_I2C_Driver_init, /* name */ 0x4C100000, // 0000 LDNIL R4 0x20100604, // 0001 NE R4 R3 R4 0x78120005, // 0002 JMPF R4 #0009 - 0xB8121200, // 0003 GETNGBL R4 K9 - 0x8C10090A, // 0004 GETMET R4 R4 K10 + 0xB8120E00, // 0003 GETNGBL R4 K7 + 0x8C100908, // 0004 GETMET R4 R4 K8 0x5C180600, // 0005 MOVE R6 R3 0x7C100400, // 0006 CALL R4 2 0x74120000, // 0007 JMPT R4 #0009 0x80000800, // 0008 RET 0 - 0x90020C02, // 0009 SETMBR R0 K6 R2 - 0xB8121200, // 000A GETNGBL R4 K9 - 0x8C10090B, // 000B GETMET R4 R4 K11 - 0x88180106, // 000C GETMBR R6 R0 K6 + 0x90020402, // 0009 SETMBR R0 K2 R2 + 0xB8120E00, // 000A GETNGBL R4 K7 + 0x8C100909, // 000B GETMET R4 R4 K9 + 0x88180102, // 000C GETMBR R6 R0 K2 0x7C100400, // 000D CALL R4 2 - 0x90020804, // 000E SETMBR R0 K4 R4 - 0x88100104, // 000F GETMBR R4 R0 K4 + 0x90020004, // 000E SETMBR R0 K0 R4 + 0x88100100, // 000F GETMBR R4 R0 K0 0x78120019, // 0010 JMPF R4 #002B 0x60100004, // 0011 GETGBL R4 G4 0x5C140200, // 0012 MOVE R5 R1 0x7C100200, // 0013 CALL R4 1 - 0x1C10090C, // 0014 EQ R4 R4 K12 + 0x1C10090A, // 0014 EQ R4 R4 K10 0x78120004, // 0015 JMPF R4 #001B 0x5C100200, // 0016 MOVE R4 R1 0x5C140000, // 0017 MOVE R5 R0 0x7C100200, // 0018 CALL R4 1 - 0x90021A04, // 0019 SETMBR R0 K13 R4 + 0x90021604, // 0019 SETMBR R0 K11 R4 0x70020000, // 001A JMP #001C - 0x90021A01, // 001B SETMBR R0 K13 R1 - 0x8810010D, // 001C GETMBR R4 R0 K13 + 0x90021601, // 001B SETMBR R0 K11 R1 + 0x8810010B, // 001C GETMBR R4 R0 K11 0x4C140000, // 001D LDNIL R5 0x1C100805, // 001E EQ R4 R4 R5 0x78120001, // 001F JMPF R4 #0022 0x4C100000, // 0020 LDNIL R4 - 0x90020804, // 0021 SETMBR R0 K4 R4 - 0x88100104, // 0022 GETMBR R4 R0 K4 + 0x90020004, // 0021 SETMBR R0 K0 R4 + 0x88100100, // 0022 GETMBR R4 R0 K0 0x78120006, // 0023 JMPF R4 #002B 0x60100001, // 0024 GETGBL R4 G1 - 0x5814000E, // 0025 LDCONST R5 K14 - 0x8818010D, // 0026 GETMBR R6 R0 K13 - 0x581C000F, // 0027 LDCONST R7 K15 - 0x88200104, // 0028 GETMBR R8 R0 K4 - 0x88201110, // 0029 GETMBR R8 R8 K16 + 0x5814000C, // 0025 LDCONST R5 K12 + 0x8818010B, // 0026 GETMBR R6 R0 K11 + 0x581C000D, // 0027 LDCONST R7 K13 + 0x88200100, // 0028 GETMBR R8 R0 K0 + 0x8820110E, // 0029 GETMBR R8 R8 K14 0x7C100800, // 002A CALL R4 4 0x80000000, // 002B RET 0 }) @@ -298,11 +141,99 @@ be_local_closure(class_I2C_Driver_init, /* name */ /******************************************************************** -** Solidified function: write8 +** Solidified function: read24 ********************************************************************/ -be_local_closure(class_I2C_Driver_write8, /* name */ +be_local_closure(class_I2C_Driver_read24, /* name */ be_nested_proto( - 9, /* nstack */ + 7, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_I2C_Driver, /* shared constants */ + &be_const_str_read24, + &be_const_str_solidified, + ( &(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 + 0x58180006, // 0004 LDCONST R6 K6 + 0x7C080800, // 0005 CALL R2 4 + 0x940C0503, // 0006 GETIDX R3 R2 K3 + 0x5412000F, // 0007 LDINT R4 16 + 0x380C0604, // 0008 SHL R3 R3 R4 + 0x94100504, // 0009 GETIDX R4 R2 K4 + 0x54160007, // 000A LDINT R5 8 + 0x38100805, // 000B SHL R4 R4 R5 + 0x000C0604, // 000C ADD R3 R3 R4 + 0x94100505, // 000D GETIDX R4 R2 K5 + 0x000C0604, // 000E ADD R3 R3 R4 + 0x80040600, // 000F RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: write_bit +********************************************************************/ +be_local_closure(class_I2C_Driver_write_bit, /* name */ + be_nested_proto( + 11, /* nstack */ + 4, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_I2C_Driver, /* shared constants */ + &be_const_str_write_bit, + &be_const_str_solidified, + ( &(const binstruction[26]) { /* code */ + 0x14100503, // 0000 LT R4 R2 K3 + 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 + 0x38120802, // 0006 SHL R4 K4 R2 + 0x780E0007, // 0007 JMPF R3 #0010 + 0x8C14010F, // 0008 GETMET R5 R0 K15 + 0x5C1C0200, // 0009 MOVE R7 R1 + 0x8C200110, // 000A GETMET R8 R0 K16 + 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 + 0x8C14010F, // 0010 GETMET R5 R0 K15 + 0x5C1C0200, // 0011 MOVE R7 R1 + 0x8C200110, // 0012 GETMET R8 R0 K16 + 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: write16LE +********************************************************************/ +be_local_closure(class_I2C_Driver_write16LE, /* name */ + be_nested_proto( + 7, /* nstack */ 3, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -311,17 +242,24 @@ be_local_closure(class_I2C_Driver_write8, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_I2C_Driver, /* shared constants */ - &be_const_str_write8, + &be_const_str_write16LE, &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x880C0104, // 0000 GETMBR R3 R0 K4 - 0x8C0C0711, // 0001 GETMET R3 R3 K17 - 0x88140106, // 0002 GETMBR R5 R0 K6 - 0x5C180200, // 0003 MOVE R6 R1 - 0x5C1C0400, // 0004 MOVE R7 R2 - 0x58200001, // 0005 LDCONST R8 K1 - 0x7C0C0A00, // 0006 CALL R3 5 - 0x80040600, // 0007 RET 1 R3 + ( &(const binstruction[15]) { /* code */ + 0x540E00FE, // 0000 LDINT R3 255 + 0x2C0C0403, // 0001 AND R3 R2 R3 + 0x54120007, // 0002 LDINT R4 8 + 0x380C0604, // 0003 SHL R3 R3 R4 + 0x5412FEFF, // 0004 LDINT R4 65280 + 0x2C100404, // 0005 AND R4 R2 R4 + 0x54160007, // 0006 LDINT R5 8 + 0x3C100805, // 0007 SHR R4 R4 R5 + 0x300C0604, // 0008 OR R3 R3 R4 + 0x5C080600, // 0009 MOVE R2 R3 + 0x8C0C0111, // 000A GETMET R3 R0 K17 + 0x5C140200, // 000B MOVE R5 R1 + 0x5C180400, // 000C MOVE R6 R2 + 0x7C0C0600, // 000D CALL R3 3 + 0x80040600, // 000E RET 1 R3 }) ) ); @@ -345,11 +283,11 @@ be_local_closure(class_I2C_Driver_read8, /* name */ &be_const_str_read8, &be_const_str_solidified, ( &(const binstruction[ 7]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 + 0x88080100, // 0000 GETMBR R2 R0 K0 0x8C080512, // 0001 GETMET R2 R2 K18 - 0x88100106, // 0002 GETMBR R4 R0 K6 + 0x88100102, // 0002 GETMBR R4 R0 K2 0x5C140200, // 0003 MOVE R5 R1 - 0x58180001, // 0004 LDCONST R6 K1 + 0x58180004, // 0004 LDCONST R6 K4 0x7C080800, // 0005 CALL R2 4 0x80040400, // 0006 RET 1 R2 }) @@ -358,6 +296,76 @@ be_local_closure(class_I2C_Driver_read8, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: read14 +********************************************************************/ +be_local_closure(class_I2C_Driver_read14, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_I2C_Driver, /* shared constants */ + &be_const_str_read14, + &be_const_str_solidified, + ( &(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 + 0x58180005, // 0004 LDCONST R6 K5 + 0x7C080800, // 0005 CALL R2 4 + 0x940C0503, // 0006 GETIDX R3 R2 K3 + 0x54120005, // 0007 LDINT R4 6 + 0x380C0604, // 0008 SHL R3 R3 R4 + 0x94100504, // 0009 GETIDX R4 R2 K4 + 0x000C0604, // 000A ADD R3 R3 R4 + 0x80040600, // 000B RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read16LE +********************************************************************/ +be_local_closure(class_I2C_Driver_read16LE, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_I2C_Driver, /* shared constants */ + &be_const_str_read16LE, + &be_const_str_solidified, + ( &(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 + 0x58180005, // 0004 LDCONST R6 K5 + 0x7C080800, // 0005 CALL R2 4 + 0x940C0504, // 0006 GETIDX R3 R2 K4 + 0x54120007, // 0007 LDINT R4 8 + 0x380C0604, // 0008 SHL R3 R3 R4 + 0x94100503, // 0009 GETIDX R4 R2 K3 + 0x000C0604, // 000A ADD R3 R3 R4 + 0x80040600, // 000B RET 1 R3 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: read12 ********************************************************************/ @@ -375,16 +383,82 @@ be_local_closure(class_I2C_Driver_read12, /* name */ &be_const_str_read12, &be_const_str_solidified, ( &(const binstruction[12]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 - 0x8C080505, // 0001 GETMET R2 R2 K5 - 0x88100106, // 0002 GETMBR R4 R0 K6 + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x88100102, // 0002 GETMBR R4 R0 K2 0x5C140200, // 0003 MOVE R5 R1 - 0x58180007, // 0004 LDCONST R6 K7 + 0x58180005, // 0004 LDCONST R6 K5 0x7C080800, // 0005 CALL R2 4 - 0x940C0500, // 0006 GETIDX R3 R2 K0 + 0x940C0503, // 0006 GETIDX R3 R2 K3 0x54120003, // 0007 LDINT R4 4 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100501, // 0009 GETIDX R4 R2 K1 + 0x94100504, // 0009 GETIDX R4 R2 K4 + 0x000C0604, // 000A ADD R3 R3 R4 + 0x80040600, // 000B RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: write8 +********************************************************************/ +be_local_closure(class_I2C_Driver_write8, /* name */ + be_nested_proto( + 9, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_I2C_Driver, /* shared constants */ + &be_const_str_write8, + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0713, // 0001 GETMET R3 R3 K19 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0400, // 0004 MOVE R7 R2 + 0x58200004, // 0005 LDCONST R8 K4 + 0x7C0C0A00, // 0006 CALL R3 5 + 0x80040600, // 0007 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read13 +********************************************************************/ +be_local_closure(class_I2C_Driver_read13, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_I2C_Driver, /* shared constants */ + &be_const_str_read13, + &be_const_str_solidified, + ( &(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 + 0x58180005, // 0004 LDCONST R6 K5 + 0x7C080800, // 0005 CALL R2 4 + 0x940C0503, // 0006 GETIDX R3 R2 K3 + 0x54120004, // 0007 LDINT R4 5 + 0x380C0604, // 0008 SHL R3 R3 R4 + 0x94100504, // 0009 GETIDX R4 R2 K4 0x000C0604, // 000A ADD R3 R3 R4 0x80040600, // 000B RET 1 R3 }) @@ -410,16 +484,16 @@ be_local_closure(class_I2C_Driver_read16, /* name */ &be_const_str_read16, &be_const_str_solidified, ( &(const binstruction[12]) { /* code */ - 0x88080104, // 0000 GETMBR R2 R0 K4 - 0x8C080505, // 0001 GETMET R2 R2 K5 - 0x88100106, // 0002 GETMBR R4 R0 K6 + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x88100102, // 0002 GETMBR R4 R0 K2 0x5C140200, // 0003 MOVE R5 R1 - 0x58180007, // 0004 LDCONST R6 K7 + 0x58180005, // 0004 LDCONST R6 K5 0x7C080800, // 0005 CALL R2 4 - 0x940C0500, // 0006 GETIDX R3 R2 K0 + 0x940C0503, // 0006 GETIDX R3 R2 K3 0x54120007, // 0007 LDINT R4 8 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100501, // 0009 GETIDX R4 R2 K1 + 0x94100504, // 0009 GETIDX R4 R2 K4 0x000C0604, // 000A ADD R3 R3 R4 0x80040600, // 000B RET 1 R3 }) @@ -428,27 +502,61 @@ be_local_closure(class_I2C_Driver_read16, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: write16 +********************************************************************/ +be_local_closure(class_I2C_Driver_write16, /* name */ + be_nested_proto( + 9, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_I2C_Driver, /* shared constants */ + &be_const_str_write16, + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0713, // 0001 GETMET R3 R3 K19 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0400, // 0004 MOVE R7 R2 + 0x58200005, // 0005 LDCONST R8 K5 + 0x7C0C0A00, // 0006 CALL R3 5 + 0x80040600, // 0007 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified class: I2C_Driver ********************************************************************/ be_local_class(I2C_Driver, 3, NULL, - be_nested_map(13, + be_nested_map(16, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(write_bit, -1), be_const_closure(class_I2C_Driver_write_bit_closure) }, - { be_const_key(addr, -1), be_const_var(1) }, { be_const_key(read32, -1), be_const_closure(class_I2C_Driver_read32_closure) }, + { be_const_key(write16, 15), be_const_closure(class_I2C_Driver_write16_closure) }, + { be_const_key(addr, -1), be_const_var(1) }, + { be_const_key(init, 1), be_const_closure(class_I2C_Driver_init_closure) }, + { be_const_key(write_bit, -1), be_const_closure(class_I2C_Driver_write_bit_closure) }, + { be_const_key(read14, -1), be_const_closure(class_I2C_Driver_read14_closure) }, + { be_const_key(name, -1), be_const_var(2) }, + { be_const_key(read8, -1), be_const_closure(class_I2C_Driver_read8_closure) }, + { be_const_key(write16LE, 11), be_const_closure(class_I2C_Driver_write16LE_closure) }, + { be_const_key(read16LE, -1), be_const_closure(class_I2C_Driver_read16LE_closure) }, + { be_const_key(read12, -1), be_const_closure(class_I2C_Driver_read12_closure) }, + { be_const_key(wire, 5), be_const_var(0) }, + { be_const_key(write8, -1), be_const_closure(class_I2C_Driver_write8_closure) }, { be_const_key(read13, -1), be_const_closure(class_I2C_Driver_read13_closure) }, { be_const_key(read16, -1), be_const_closure(class_I2C_Driver_read16_closure) }, - { be_const_key(read14, -1), be_const_closure(class_I2C_Driver_read14_closure) }, - { be_const_key(read24, 12), be_const_closure(class_I2C_Driver_read24_closure) }, - { be_const_key(name, 4), be_const_var(2) }, - { be_const_key(write8, -1), be_const_closure(class_I2C_Driver_write8_closure) }, - { be_const_key(wire, 8), be_const_var(0) }, - { be_const_key(read8, -1), be_const_closure(class_I2C_Driver_read8_closure) }, - { be_const_key(read12, -1), be_const_closure(class_I2C_Driver_read12_closure) }, - { be_const_key(init, -1), be_const_closure(class_I2C_Driver_init_closure) }, + { be_const_key(read24, -1), be_const_closure(class_I2C_Driver_read24_closure) }, })), (bstring*) &be_const_str_I2C_Driver ); From c2091d7082706d71f9c42f5ff54f591c2b733d66 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Nov 2024 23:26:46 +0100 Subject: [PATCH 093/205] Fix FUNC_COMMAND linked list command buffer corruption by shutter driver --- CHANGELOG.md | 3 ++- RELEASENOTES.md | 2 ++ .../tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino | 8 ++++++-- tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino | 13 +++++-------- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47a3d7f5f..277e197e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to this project will be documented in this file. - Support KNX for scripts (#22429) - Support deep sleep (standby) for VL53L0X (#22441) - Support for MS5837 pressure and temperature sensor (#22376) -- Berry add I2C read16/write16 supporting Little Endian +- Berry add I2C read16/write16 supporting Little Endian (#22448) ### Breaking Changed @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. ### Fixed - ESP32-S3 UART output mode for Tx (#22426) - Mitsubishi Electric HVAC Standby Stage for MiElHVAC (#22430) +- FUNC_COMMAND linked list command buffer corruption by shutter driver ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d8ced5db0..6384dfd72 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -137,6 +137,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC [#22370](https://github.com/arendst/Tasmota/issues/22370) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) +- Berry add I2C read16/write16 supporting Little Endian [#22448](https://github.com/arendst/Tasmota/issues/22448) - HASPmota `haspmota.get_pages()` to get the sorted list of pages [#22358](https://github.com/arendst/Tasmota/issues/22358) ### Breaking Changed @@ -156,6 +157,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed +- FUNC_COMMAND linked list command buffer corruption by shutter driver - Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) - Mitsubishi Electric HVAC Standby Stage for MiElHVAC [#22430](https://github.com/arendst/Tasmota/issues/22430) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index cff8dc1f8..3371ffe65 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -2293,6 +2293,7 @@ bool Xdrv27(uint32_t function) if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support uint8_t counter = XdrvMailbox.index == 0 ? 1 : XdrvMailbox.index; uint8_t counterend = XdrvMailbox.index == 0 ? TasmotaGlobal.shutters_present : XdrvMailbox.index; + uint32_t rescue_index = XdrvMailbox.index; int32_t rescue_payload = XdrvMailbox.payload; uint32_t rescue_data_len = XdrvMailbox.data_len; char stemp1[10]; @@ -2323,7 +2324,7 @@ bool Xdrv27(uint32_t function) XdrvMailbox.index = i; XdrvMailbox.payload = rescue_payload; XdrvMailbox.data_len = rescue_data_len; - if (!ShutterSettings.version) { + if (!ShutterSettings.version) { ShutterSettingsLoad(0); ShutterSettings.shutter_startrelay[0] = 1; ShutterInit(); @@ -2395,13 +2396,16 @@ bool Xdrv27(uint32_t function) break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: - ShutterShow(); +// ShutterShow(); break; #endif // USE_WEBSERVER case FUNC_ACTIVE: result = true; break; } + XdrvMailbox.index = rescue_index; + XdrvMailbox.payload = rescue_payload; + XdrvMailbox.data_len = rescue_data_len; } return result; } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index e433134d5..3602b18d7 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -1899,6 +1899,7 @@ bool Xdrv27(uint32_t function) if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support uint8_t counter = XdrvMailbox.index==0?1:XdrvMailbox.index; uint8_t counterend = XdrvMailbox.index==0?TasmotaGlobal.shutters_present:XdrvMailbox.index; + uint32_t rescue_index = XdrvMailbox.index; int32_t rescue_payload = XdrvMailbox.payload; uint32_t rescue_data_len = XdrvMailbox.data_len; char stemp1[10]; @@ -1922,13 +1923,6 @@ bool Xdrv27(uint32_t function) result = DecodeCommand(kShutterCommands, ShutterCommand); } break; - for (uint8_t i = counter; i <= counterend; i++) { - XdrvMailbox.index = i; - XdrvMailbox.payload = rescue_payload; - XdrvMailbox.data_len = rescue_data_len; - result = DecodeCommand(kShutterCommands, ShutterCommand); - } - break; case FUNC_JSON_APPEND: if (!sensor_data_reported) { sensor_data_reported = true; @@ -1984,13 +1978,16 @@ bool Xdrv27(uint32_t function) break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: - ShutterShow(); +// ShutterShow(); break; #endif // USE_WEBSERVER case FUNC_ACTIVE: result = true; break; } + XdrvMailbox.index = rescue_index; + XdrvMailbox.payload = rescue_payload; + XdrvMailbox.data_len = rescue_data_len; } return result; } From a836e841ad76069b8a29a8d610b56ddc6981dbdd Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Nov 2024 23:53:29 +0100 Subject: [PATCH 094/205] Re-enable shuttershow regression from last PR --- tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index 3371ffe65..3f0ec5201 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -2396,7 +2396,7 @@ bool Xdrv27(uint32_t function) break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: -// ShutterShow(); + ShutterShow(); break; #endif // USE_WEBSERVER case FUNC_ACTIVE: diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 3602b18d7..a6d1d0da0 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -1978,7 +1978,7 @@ bool Xdrv27(uint32_t function) break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: -// ShutterShow(); + ShutterShow(); break; #endif // USE_WEBSERVER case FUNC_ACTIVE: From 3bc90175dbddaa83eb8d8020a1c921b748bbc2a0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:24:40 +0100 Subject: [PATCH 095/205] Fix ESP32, ESP32-S2 and ESP32-S3 re-enable touch buttons (#22446) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/include/tasmota.h | 8 ++++++++ 3 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 277e197e5..21dc9df14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ All notable changes to this project will be documented in this file. - ESP32-S3 UART output mode for Tx (#22426) - Mitsubishi Electric HVAC Standby Stage for MiElHVAC (#22430) - FUNC_COMMAND linked list command buffer corruption by shutter driver +- ESP32, ESP32-S2 and ESP32-S3 re-enable touch buttons (#22446) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 6384dfd72..8f79ce8f1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -163,6 +163,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 [#22367](https://github.com/arendst/Tasmota/issues/22367) - ESP32 Arduino Core IPv6 zones used by Matter [#22378](https://github.com/arendst/Tasmota/issues/22378) +- ESP32, ESP32-S2 and ESP32-S3 re-enable touch buttons [#22446](https://github.com/arendst/Tasmota/issues/22446) - ESP32-S3 UART output mode for Tx [#22426](https://github.com/arendst/Tasmota/issues/22426) ### Removed diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index 627596474..ca775b88e 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -336,6 +336,14 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to #define WIFI_SENSITIVITY_n -720 #endif +#ifdef ESP32 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#define SOC_TOUCH_VERSION_1 +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +#define SOC_TOUCH_VERSION_2 +#endif // SOC_TOUCH_SENSOR_VERSION +#endif // ESP32 + /*********************************************************************************************\ * Enumeration \*********************************************************************************************/ From a5c33eba5ef731b9e3af28364d2b49cf89bdcabd Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Sat, 9 Nov 2024 19:29:29 +0100 Subject: [PATCH 096/205] Berry drivers for PCA9535 (generic and in SenseCAP D1) (#22451) --- CHANGELOG.md | 1 + .../src/be_i2c_axp192_axp202_lib.c | 2 +- tasmota/berry/drivers/PCA9535.be | 82 +++++++++++++++++++ tasmota/berry/drivers/PCA9535_SenseCAP_D1.be | 42 ++++++++++ 4 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 tasmota/berry/drivers/PCA9535.be create mode 100644 tasmota/berry/drivers/PCA9535_SenseCAP_D1.be diff --git a/CHANGELOG.md b/CHANGELOG.md index 21dc9df14..4defcfc7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - Support deep sleep (standby) for VL53L0X (#22441) - Support for MS5837 pressure and temperature sensor (#22376) - Berry add I2C read16/write16 supporting Little Endian (#22448) +- Berry drivers for PCA9535 (generic and in SenseCAP D1) ### Breaking Changed diff --git a/lib/libesp32/berry_tasmota/src/be_i2c_axp192_axp202_lib.c b/lib/libesp32/berry_tasmota/src/be_i2c_axp192_axp202_lib.c index aec926077..f121b1708 100644 --- a/lib/libesp32/berry_tasmota/src/be_i2c_axp192_axp202_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_i2c_axp192_axp202_lib.c @@ -1,5 +1,5 @@ /******************************************************************** - * Tasmota LVGL lv_signal_bars widget + * Drivers for AXP192 and AXP202 I2C Solidified *******************************************************************/ #include "solidify/solidified_i2c_axp192.h" #include "solidify/solidified_i2c_axp202.h" diff --git a/tasmota/berry/drivers/PCA9535.be b/tasmota/berry/drivers/PCA9535.be new file mode 100644 index 000000000..e5328caa4 --- /dev/null +++ b/tasmota/berry/drivers/PCA9535.be @@ -0,0 +1,82 @@ +################################################################################# +# Generic driver for PCA9535 - solidified +# +# I2C IO Expander, similar to PCA9557 +# Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA9535_PCA9535C.pdf +# +# This expander is used in SeedStudio SenseCAP D1 +################################################################################# + +#@ solidify:PCA9535 +class PCA9535 : I2C_Driver + var last_read # time when last read (avoid reading too often) + var input_port # shadow of registers 0+1 with state of input registers + var output_port # shadow of registers 2+3 with known outputs + var inversion_port # shadow of registers 4+5 with input inversion + var config_port # shadow of registers 6+7 with Input/Output configurations + + def init(address) + if (address == nil) address = 0x20 end # default address is 0x20 + super(self).init("PCA9535", address) + self.last_read = 0 + if self.wire + # if detected + self.read_all() + end + end + + def read_all() + var now = tasmota.millis() + if (now - self.last_read > 10) # if last read was more than 10 ms in the past + self.input_port = self.read16LE(0x00) + self.output_port = self.read16LE(0x02) + self.inversion_port = self.read16LE(0x04) + self.config_port = self.read16LE(0x06) + self.last_read = tasmota.millis() + if tasmota.loglevel(4) + log(f"I2C: PCA9535 read input(0x{self.input_port:04X}) output(0x{self.output_port:04X}) inversion(0x{self.inversion_port:04X}) config(0x{self.config_port:04X})") + end + end + end + + def config_all(v) + self.config_port = int(v) + self.write16LE(0x06, self.config_port) + end + # port: 0..15 + # mode: 0=output 1=input + def config_gpio(port, mode) + self.read_all() + if (mode != 0 && mode != 1) raise "value_error", f"mode muste be 0 or 1" end + var config_new = self._bit_set_to(self.config_port, port, mode) + # write only if value changed + if config_new != self.config_port + self.config_all(config_new) + end + end + + def read_gpio(port) + self.read_all() + return (self.input_port & (1 << port)) ? 1 : 0 + end + + def write_gpio(port, v) + self.read_all() + v = (v ? 1 : 0) # ensure we have only 0/1 as values + var output_new = self._bit_set_to(self.output_port, port, v) + if output_new != self.output_port + self.output_port = output_new + self.write16LE(0x02, self.output_port) + end + end + + # inspired from https://stackoverflow.com/questions/47981/how-to-set-clear-and-toggle-a-single-bit + # num: int value + # n: bit to change + # x: value 0/1 + static def _bit_set_to(num, n, x) + return (num & ~(1 << n)) | (x << n) + end +end + +return PCA9535 diff --git a/tasmota/berry/drivers/PCA9535_SenseCAP_D1.be b/tasmota/berry/drivers/PCA9535_SenseCAP_D1.be new file mode 100644 index 000000000..7afd9d928 --- /dev/null +++ b/tasmota/berry/drivers/PCA9535_SenseCAP_D1.be @@ -0,0 +1,42 @@ +################################################################################# +# Specialized driver for SeedStudio SenseCAP D1 display +################################################################################# + +import PCA9535 + +class PCA9535_SenseCAP_D1 : PCA9535 + def init() + super(self).init(0x20) + + if self.wire + self.write_gpio(0x05, 1) # set IO0.5 (LCD_RESET) high + self.write_gpio(0x07, 1) # set IO0.7 (TOUCH_RESET) high + self.write_gpio(0x08, 1) # set IO1.0 (RP2040_RESET) high + self.config_gpio(0x05, 0) # configure IO0.5 (LCD_RESET) as output + self.config_gpio(0x07, 0) # configure IO0.7 (TOUCH_RESET) as output + self.config_gpio(0x08, 0) # configure IO1.0 (RP2040_RESET) as output + # reset display at boot + self.reset_display() + end + end + + # hardware reset for the MCU RP2040 + def reset_RP2040() + self.write_gpio(0x08, 0) # drive RESET Low + tasmota.delay(2) # the recommended delay is 1ms, we take some margin + self.write_gpio(0x08, 1) # drive RESET High + end + + # reset both display and touch screen + def reset_display() + self.write_gpio(0x05, 0) + self.write_gpio(0x07, 0) + tasmota.delay(2) + self.write_gpio(0x05, 1) + self.write_gpio(0x07, 1) + tasmota.delay(50) + end + +end + +return PCA9535_SenseCAP_D1() From 669c6e49ea7a0d02659c986aee0ac40925519d1c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 10 Nov 2024 11:18:18 +0100 Subject: [PATCH 097/205] Update changelogs --- CHANGELOG.md | 2 +- RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4defcfc7b..01fe6b01c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file. - Support deep sleep (standby) for VL53L0X (#22441) - Support for MS5837 pressure and temperature sensor (#22376) - Berry add I2C read16/write16 supporting Little Endian (#22448) -- Berry drivers for PCA9535 (generic and in SenseCAP D1) +- Berry drivers for PCA9535 (generic and in SenseCAP D1) (#22451) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 8f79ce8f1..fe1fede6a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -138,6 +138,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) - Berry add I2C read16/write16 supporting Little Endian [#22448](https://github.com/arendst/Tasmota/issues/22448) +- Berry drivers for PCA9535 (generic and in SenseCAP D1) [#22451](https://github.com/arendst/Tasmota/issues/22451) - HASPmota `haspmota.get_pages()` to get the sorted list of pages [#22358](https://github.com/arendst/Tasmota/issues/22358) ### Breaking Changed From 7e3f093dc947d7bd39eadd44b703d8d5859e545b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 10 Nov 2024 11:46:52 +0100 Subject: [PATCH 098/205] Change GUI ajax updating buttons/sliders/shutters --- .../xdrv_01_9_webserver.ino | 433 +++++++++++++----- .../xdrv_27_esp32_shutter.ino | 2 +- .../tasmota_xdrv_driver/xdrv_27_shutter.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 47 +- 4 files changed, 343 insertions(+), 141 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index a452417ef..69272c8da 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -267,12 +267,14 @@ const char HTTP_HEAD_STYLE3[] PROGMEM = "

%s

"; // Device name const char HTTP_MSG_SLIDER_GRADIENT[] PROGMEM = + "" "
" "" - "
"; + "" + ""; -const char HTTP_MSG_SLIDER_UPDATE[] PROGMEM = - "
"; @@ -416,7 +418,10 @@ const char HTTP_END[] PROGMEM = "" ""; -const char HTTP_DEVICE_CONTROL[] PROGMEM = ""; // ?o is related to WebGetArg(PSTR("o"), tmp, sizeof(tmp)) +//const char HTTP_DEVICE_CONTROL[] PROGMEM = ""; // ?o is related to WebGetArg(PSTR("o"), tmp, sizeof(tmp)) +//const char HTTP_DEVICE_CONTROL[] PROGMEM = ""; // ?o is related to WebGetArg(PSTR("o"), tmp, sizeof(tmp)) +const char HTTP_DEVICE_CONTROL[] PROGMEM = ""; // ?o is related to WebGetArg(PSTR("o"), tmp, sizeof(tmp)) + const char HTTP_DEVICE_STATE[] PROGMEM = "%s"; enum ButtonTitle { @@ -464,6 +469,7 @@ struct WEB { uint32_t upload_size = 0; int slider[LST_MAX]; uint16_t upload_error = 0; + uint8_t slider_update[LST_MAX]; uint8_t state = HTTP_OFF; uint8_t upload_file_type; uint8_t config_block_count = 0; @@ -602,6 +608,7 @@ void StartWebserver(int type) for (uint32_t i = 0; i < LST_MAX; i++) { Web.slider[i] = -1; + Web.slider_update[i] = 0; } if (!Webserver) { @@ -1150,31 +1157,30 @@ uint32_t WebUseManagementSubmenu(void) { return management_count -1; } -uint32_t WebDeviceColumns(void) { - const uint32_t max_columns = 8; - - uint32_t rows = TasmotaGlobal.devices_present / max_columns; - if (TasmotaGlobal.devices_present % max_columns) { rows++; } - uint32_t cols = TasmotaGlobal.devices_present / rows; - if (TasmotaGlobal.devices_present % rows) { cols++; } - return cols; -} - #ifdef USE_LIGHT void WebSliderColdWarm(void) { Web.slider[0] = LightGetColorTemp(); + WSContentSend_P(PSTR("")); WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Cold Warm - PSTR("a"), // a - Unique HTML id + 2, 100, + PSTR("a"), // a - Unique HTML id PSTR("#eff"), PSTR("#f81"), // 6500k in RGB (White) to 2500k in RGB (Warm Yellow) 1, // sl1 - used for slider updates 153, 500, // Range color temperature Web.slider[0], 't', 0); // t0 - Value id releated to lc("t0", value) and WebGetArg("t0", tmp, sizeof(tmp)); + WSContentSend_P(PSTR("")); } #endif // USE_LIGHT -void HandleRoot(void) -{ +const char HTTP_MSG_SLIDER_SHUTTERT[] PROGMEM = + "" + "
%s" + "" + "
" + ""; + +void HandleRoot(void) { #ifndef NO_CAPTIVE_PORTAL if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the page. #endif // NO_CAPTIVE_PORTAL @@ -1206,6 +1212,18 @@ void HandleRoot(void) AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_MAIN_MENU)); + /* + Display GUI with items in following order: + - Header with module name and device name + - Dynamic ajax update region + - Optional power toggle buttons for relays, display and iFan with feedback + - Optional shutter buttons and slider with feedback + - Optional light button and slider(s) with feedback + - Call FUNC_WEB_ADD_MAIN_BUTTON + - Optional buttons and sliders with feedback + - Show default main buttons (Configuration, Information, Firmware Upgrade, Tools and Restart) + */ + char stemp[33]; WSContentStart_P(PSTR(D_MAIN_MENU)); @@ -1215,16 +1233,129 @@ void HandleRoot(void) WSContentSend_P(HTTP_SCRIPT_ROOT, Settings->web_refresh); #endif WSContentSend_P(HTTP_SCRIPT_ROOT_PART2); - WSContentSendStyle(); - WSContentSend_P(PSTR("
")); + if (TasmotaGlobal.devices_present) { + uint32_t buttons_non_light = TasmotaGlobal.devices_present; + uint32_t button_idx = 1; + +#ifdef USE_LIGHT + // Chk for reduced toggle buttons used by lights + if (TasmotaGlobal.light_type) { + // Find and skip light buttons (Lights are controlled by the last TasmotaGlobal.devices_present (or 2)) + buttons_non_light = LightDevice() -1; + } +#endif // USE_LIGHT + + uint32_t buttons_non_light_non_shutter = buttons_non_light; + +#ifdef USE_SHUTTER + // Chk for reduced toggle buttons used by shutters + uint32_t shutter_button = 0; // Bitmask for each button + + // Find and skip dedicated shutter buttons + if (buttons_non_light && Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support + for (button_idx = 1; button_idx <= buttons_non_light; button_idx++) { + if (IsShutterWebButton(button_idx) != 0) { + buttons_non_light_non_shutter--; + shutter_button |= (1 << (button_idx -1)); // Set button bit in bitmask + } + } + } +#endif // USE_SHUTTER + + if (buttons_non_light_non_shutter) { // Any non light AND non shutter button + // Display toggle buttons + WSContentSend_P(HTTP_TABLE100); // "" + WSContentSend_P(PSTR("")); + +#ifdef USE_SONOFF_IFAN + if (IsModuleIfan()) { + WSContentSend_P(HTTP_DEVICE_CONTROL, 36, 1, 1, + (strlen(SettingsText(SET_BUTTON1))) ? SettingsTextEscaped(SET_BUTTON1).c_str() : PSTR(D_BUTTON_TOGGLE), + ""); + for (uint32_t i = 0; i < MaxFanspeed(); i++) { + snprintf_P(stemp, sizeof(stemp), PSTR("%d"), i); + WSContentSend_P(HTTP_DEVICE_CONTROL, 16, i +2, i +2, + (strlen(SettingsText(SET_BUTTON2 + i))) ? SettingsTextEscaped(SET_BUTTON2 + i).c_str() : stemp, + ""); + } + } else { +#endif // USE_SONOFF_IFAN + + const uint32_t max_columns = 8; + uint32_t rows = buttons_non_light_non_shutter / max_columns; + if (buttons_non_light_non_shutter % max_columns) { rows++; } + uint32_t cols = buttons_non_light_non_shutter / rows; + if (buttons_non_light_non_shutter % rows) { cols++; } + + uint32_t button_ptr = 0; + for (button_idx = 1; button_idx <= buttons_non_light; button_idx++) { + +#ifdef USE_SHUTTER + if (bitRead(shutter_button, button_idx -1)) { continue; } // Skip non-sequential shutter button +#endif // USE_SHUTTER + + bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); + snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), button_idx); + WSContentSend_P(HTTP_DEVICE_CONTROL, 100 / cols, button_idx, button_idx, + (set_button) ? HtmlEscape(GetWebButton(button_idx -1)).c_str() : (cols < 5) ? PSTR(D_BUTTON_TOGGLE) : "", + (set_button) ? "" : (TasmotaGlobal.devices_present > 1) ? stemp : ""); + button_ptr++; + if (0 == button_ptr % cols) { WSContentSend_P(PSTR("")); } + } +#ifdef USE_SONOFF_IFAN + } +#endif // USE_SONOFF_IFAN + + WSContentSend_P(PSTR("
")); + } + +#ifdef USE_SHUTTER + if (shutter_button) { // Any button bit set + WSContentSend_P(HTTP_TABLE100); // "" + + int32_t ShutterWebButton; + uint32_t shutter_button_idx = 1; + for (uint32_t shutter_idx = 0; shutter_idx < TasmotaGlobal.shutters_present ; shutter_idx++) { + while ((0 == shutter_button & (1 << (shutter_button_idx -1)))) { shutter_button_idx++; } + + WSContentSend_P(PSTR("")); + shutter_button_idx++; // Left button is next button first (down) + for (uint32_t j = 0; j < 2; j++) { + ShutterWebButton = IsShutterWebButton(shutter_button_idx); + WSContentSend_P(HTTP_DEVICE_CONTROL, 15, shutter_button_idx, shutter_button_idx, + ((ShutterGetOptions(abs(ShutterWebButton)-1) & 2) /* is locked */ ? "-" : + ((ShutterGetOptions(abs(ShutterWebButton)-1) & 8) /* invert web buttons */ ? ((ShutterWebButton>0) ? "▼" : "▲") : ((ShutterWebButton>0) ? "▲" : "▼"))), + ""); + + if (1 == j) { break; } + + shutter_button_idx--; // Right button is previous button (up) + bool set_button = ((shutter_button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(shutter_button_idx -1))); + snprintf_P(stemp, sizeof(stemp), PSTR("Shutter %d"), shutter_idx +1); + WSContentSend_P(HTTP_MSG_SLIDER_SHUTTERT, + (set_button) ? HtmlEscape(GetWebButton(shutter_button_idx -1)).c_str() : stemp, + shutter_idx +1, + (ShutterGetOptions(shutter_idx) & 1) ? (100 - ShutterRealToPercentPosition(-9999, shutter_idx)) : ShutterRealToPercentPosition(-9999, shutter_idx), + shutter_idx +1); + } + WSContentSend_P(PSTR("")); + shutter_button_idx += 2; + + } + WSContentSend_P(PSTR("
")); + } +#endif // USE_SHUTTER + #ifdef USE_LIGHT if (TasmotaGlobal.light_type) { + WSContentSend_P(HTTP_TABLE100); // "" + uint8_t light_subtype = TasmotaGlobal.light_type &7; if (!Settings->flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM - bool split_white = ((LST_RGBW <= light_subtype) && (TasmotaGlobal.devices_present > 1)); // Only on RGBW or RGBCW and SetOption37 128 + bool split_white = ((LST_RGBW <= light_subtype) && (TasmotaGlobal.devices_present > 1) && (Settings->param[P_RGB_REMAP] & 128)); // Only on RGBW or RGBCW and SetOption37 128 if ((LST_COLDWARM == light_subtype) || ((LST_RGBCW == light_subtype) && !split_white)) { WebSliderColdWarm(); @@ -1236,13 +1367,16 @@ void HandleRoot(void) LightGetHSB(&hue, &sat, nullptr); Web.slider[1] = hue; + WSContentSend_P(PSTR("")); WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Hue - PSTR("b"), // b - Unique HTML id + 2, 100, + PSTR("b"), // b - Unique HTML id PSTR("#800"), PSTR("#f00 5%,#ff0 20%,#0f0 35%,#0ff 50%,#00f 65%,#f0f 80%,#f00 95%,#800"), // Hue colors 2, // sl2 - Unique range HTML id - Used as source for Saturation end color and slider updates 0, 359, // Range valid Hue Web.slider[1], 'h', 0); // h0 - Value id + WSContentSend_P(PSTR("")); uint8_t dcolor = changeUIntScale(Settings->light_dimmer, 0, 100, 0, 255); char scolor[8]; @@ -1252,95 +1386,136 @@ void HandleRoot(void) snprintf_P(stemp, sizeof(stemp), PSTR("#%02X%02X%02X"), red, green, blue); // Saturation end color Web.slider[2] = changeUIntScale(sat, 0, 255, 0, 100); + WSContentSend_P(PSTR("")); WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Saturation - PSTR("s"), // s - Unique HTML id related to eb('s').style.background='linear-gradient(to right,rgb('+sl+'%%,'+sl+'%%,'+sl+'%%),hsl('+eb('sl2').value+',100%%,50%%))'; + 2, 100, + PSTR("s"), // s - Unique HTML id related to eb('s').style.background='linear-gradient(to right,rgb('+sl+'%%,'+sl+'%%,'+sl+'%%),hsl('+eb('sl2').value+',100%%,50%%))'; scolor, stemp, // Brightness to max current color 3, // sl3 - Unique range HTML id - Used for slider updates 0, 100, // Range 0 to 100% Web.slider[2], 'n', 0); // n0 - Value id + WSContentSend_P(PSTR("")); } + bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); + char first[2]; + snprintf_P(first, sizeof(first), PSTR("%s"), PSTR(D_BUTTON_TOGGLE)); + char butt_txt[4]; + snprintf_P(butt_txt, sizeof(butt_txt), PSTR("%s"), (set_button) ? HtmlEscape(GetWebButton(button_idx -1)).c_str() : first); + char number[8]; + WSContentSend_P(PSTR("")); + WSContentSend_P(HTTP_DEVICE_CONTROL, 15, button_idx, button_idx, + butt_txt, + (set_button) ? "" : itoa(button_idx, number, 10)); + button_idx++; + Web.slider[3] = Settings->light_dimmer; WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Brightness - Black to White - PSTR("c"), // c - Unique HTML id + 1, 85, + PSTR("c"), // c - Unique HTML id PSTR("#000"), PSTR("#fff"), // Black to White 4, // sl4 - Unique range HTML id - Used as source for Saturation begin color and slider updates Settings->flag3.slider_dimmer_stay_on, 100, // Range 0/1 to 100% (SetOption77 - Do not power off if slider moved to far left) Web.slider[3], 'd', 0); // d0 - Value id is related to lc("d0", value) and WebGetArg("d0", tmp, sizeof(tmp)); + WSContentSend_P(PSTR("")); if (split_white) { // SetOption37 128 if (LST_RGBCW == light_subtype) { WebSliderColdWarm(); } + + uint32_t width = 100; + WSContentSend_P(PSTR("")); + + if (button_idx <= TasmotaGlobal.devices_present) { + bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); + char first[2]; + snprintf_P(first, sizeof(first), PSTR("%s"), PSTR(D_BUTTON_TOGGLE)); + char butt_txt[4]; + snprintf_P(butt_txt, sizeof(butt_txt), PSTR("%s"), (set_button) ? HtmlEscape(GetWebButton(button_idx -1)).c_str() : first); + char number[8]; + WSContentSend_P(HTTP_DEVICE_CONTROL, 15, button_idx, button_idx, + butt_txt, + (set_button) ? "" : itoa(button_idx, number, 10)); + button_idx++; + width = 85; + } + Web.slider[4] = LightGetDimmer(2); WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // White brightness - Black to White - PSTR("f"), // f - Unique HTML id - PSTR("#000"), PSTR("#fff"), // Black to White + (100 == width) ? 2 : 1, width, + PSTR("f"), // f - Unique HTML id + PSTR("#000"), PSTR("#fff"), // Black to White 5, // sl5 - Unique range HTML id - Used for slider updates Settings->flag3.slider_dimmer_stay_on, 100, // Range 0/1 to 100% (SetOption77 - Do not power off if slider moved to far left) Web.slider[4], 'w', 0); // w0 - Value id is related to lc("w0", value) and WebGetArg("w0", tmp, sizeof(tmp)); + WSContentSend_P(PSTR("")); } } else { // Settings->flag3.pwm_multi_channels - SetOption68 1 - Enable multi-channels PWM instead of Color PWM - uint32_t pwm_channels = light_subtype > LST_MAX ? LST_MAX : light_subtype; + uint32_t pwm_channels = TasmotaGlobal.devices_present - buttons_non_light; stemp[0] = 'e'; stemp[1] = '0'; stemp[2] = '\0'; // d0 for (uint32_t i = 0; i < pwm_channels; i++) { - stemp[1]++; // e1 to e5 - Make unique ids + bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); + char first[2]; + snprintf_P(first, sizeof(first), PSTR("%s"), PSTR(D_BUTTON_TOGGLE)); + char butt_txt[4]; + snprintf_P(butt_txt, sizeof(butt_txt), PSTR("%s"), + (set_button) ? HtmlEscape(GetWebButton(button_idx -1)).c_str() : first); + char number[8]; + WSContentSend_P(PSTR("")); + WSContentSend_P(HTTP_DEVICE_CONTROL, 15, button_idx, button_idx, + butt_txt, + (set_button) ? "" : itoa(button_idx, number, 10)); + button_idx++; + stemp[1]++; // e1 to e5 - Make unique ids Web.slider[i] = changeUIntScale(Settings->light_color[i], 0, 255, 0, 100); + WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Channel brightness - Black to White + 1, 85, stemp, // e1 to e5 - Unique HTML id PSTR("#000"), PSTR("#fff"), // Black to White i+1, // sl1 to sl5 - Unique range HTML id - Used for slider updates 1, 100, // Range 1 to 100% Web.slider[i], 'e', i+1); // e1 to e5 - Value id + + WSContentSend_P(PSTR("")); } } // Settings->flag3.pwm_multi_channels + WSContentSend_P(PSTR("
")); } #endif // USE_LIGHT - WSContentSend_P(HTTP_TABLE100); - WSContentSend_P(PSTR("")); + + } + + // Init buttons + WSContentSend_P(PSTR("")); #ifndef FIRMWARE_MINIMAL XdrvXsnsCall(FUNC_WEB_ADD_MAIN_BUTTON); @@ -1507,44 +1682,94 @@ bool HandleRootStatusRefresh(void) WSContentBegin(200, CT_HTML); #endif // USE_WEB_SSE + bool msg_exec_javascript = false; + if (TasmotaGlobal.devices_present) { + // Update changed web buttons + uint32_t max_devices = TasmotaGlobal.devices_present; + +#ifdef USE_SONOFF_IFAN + uint32_t fanspeed; + if (IsModuleIfan()) { + // Single power relay and four virtual buttons + max_devices = MaxFanspeed() +1; // 4 -> 5 + fanspeed = GetFanspeed() +2; // 0..3 -> 2..5 + } +#endif // USE_SONOFF_IFAN + + WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // " 1)) { + active = (fanspeed == idx); + } +#endif // USE_SONOFF_IFAN + + WSContentSend_P(PSTR("eb('o%d').style.background='#%06x';"), + idx, WebColor((active) ? COL_BUTTON : COL_FORM)); + } + } + +#ifdef USE_SHUTTER + if (!msg_exec_javascript) { + WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "flag6.disable_slider_updates) { // SetOption161 0 - (Light) Disable slider updates (1) - uint16_t hue; - uint8_t sat; - int current_value = -1; - for (uint32_t i = 0; i < LST_MAX; i++) { - if (Web.slider[i] != -1) { - if (!Settings->flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM - if (0 == i) { - current_value = LightGetColorTemp(); - } - else if (1 == i) { - LightGetHSB(&hue, &sat, nullptr); - current_value = hue; - } - else if (2 == i) { - current_value = changeUIntScale(sat, 0, 255, 0, 100); - } - else if (3 == i) { - current_value = Settings->light_dimmer; - } - else if (4 == i) { - current_value = LightGetDimmer(2); - } - } else { - current_value = changeUIntScale(Settings->light_color[i], 0, 255, 0, 100); + uint16_t hue; + uint8_t sat; + int current_value = -1; + for (uint32_t i = 0; i < LST_MAX; i++) { + if (Web.slider[i] != -1) { + if (!Settings->flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM + if (0 == i) { + current_value = LightGetColorTemp(); } - if (current_value != Web.slider[i]) { + else if (1 == i) { + LightGetHSB(&hue, &sat, nullptr); + current_value = hue; + } + else if (2 == i) { + current_value = changeUIntScale(sat, 0, 255, 0, 100); + } + else if (3 == i) { + current_value = Settings->light_dimmer; + } + else if (4 == i) { + current_value = LightGetDimmer(2); + } + } else { + current_value = changeUIntScale(Settings->light_color[i], 0, 255, 0, 100); + } + if (current_value != Web.slider[i]) { + Web.slider_update[i]++; + if (Web.slider_update[i] > 2) { // Allow two other users screen sync + Web.slider_update[i] = 0; Web.slider[i] = current_value; - // https://stackoverflow.com/questions/4057236/how-to-add-onload-event-to-a-div-element - WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""), i +1, current_value); } + // https://stackoverflow.com/questions/4057236/how-to-add-onload-event-to-a-div-element + if (!msg_exec_javascript) { + WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "")); + } + WSContentSend_P(PSTR("{t}")); // WSContentSeparator(3); // Reset seperator to ignore previous outputs if (Settings->web_time_end) { @@ -1554,30 +1779,6 @@ bool HandleRootStatusRefresh(void) XsnsXdrvCall(FUNC_WEB_SENSOR); WSContentSend_P(PSTR("
")); - if (TasmotaGlobal.devices_present) { - WSContentSend_P(PSTR("{t}")); -#ifdef USE_SONOFF_IFAN - if (IsModuleIfan()) { - WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(TasmotaGlobal.power, 0)) ? PSTR("bold") : PSTR("normal"), 54, GetStateText(bitRead(TasmotaGlobal.power, 0))); - uint32_t fanspeed = GetFanspeed(); - snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fanspeed); - WSContentSend_P(HTTP_DEVICE_STATE, 64, (fanspeed) ? PSTR("bold") : PSTR("normal"), 54, (fanspeed) ? svalue : GetStateText(0)); - } else { -#endif // USE_SONOFF_IFAN - uint32_t cols = WebDeviceColumns(); - uint32_t fontsize = (cols < 5) ? 70 - (cols * 8) : 32; - for (uint32_t idx = 1; idx <= TasmotaGlobal.devices_present; idx++) { - snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(TasmotaGlobal.power, idx -1)); - WSContentSend_P(HTTP_DEVICE_STATE, 100 / cols, (bitRead(TasmotaGlobal.power, idx -1)) ? PSTR("bold") : PSTR("normal"), fontsize, - (cols < 5) ? GetStateText(bitRead(TasmotaGlobal.power, idx -1)) : svalue); - if (0 == idx % cols) { WSContentSend_P(PSTR("")); } - } -#ifdef USE_SONOFF_IFAN - } -#endif // USE_SONOFF_IFAN - - WSContentSend_P(PSTR("")); - } WSContentSend_P(PSTR("\n\n")); // Prep for SSE WSContentEnd(); @@ -1754,12 +1955,12 @@ void HandleTemplateConfiguration(void) { WSContentSendStyle(); WSContentSend_P(HTTP_FORM_TEMPLATE); - WSContentSend_P(HTTP_TABLE100); + WSContentSend_P(HTTP_TABLE100); // "" WSContentSend_P(PSTR("" "" "
" D_TEMPLATE_NAME "
" D_BASE_TYPE "
" "
")); - WSContentSend_P(HTTP_TABLE100); + WSContentSend_P(HTTP_TABLE100); // "" for (uint32_t i = 0; i < MAX_GPIO_PIN; i++) { #if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 // ESP32C2/C3/C6 all gpios are in the template, flash are hidden diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index 3f0ec5201..3371ffe65 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -2396,7 +2396,7 @@ bool Xdrv27(uint32_t function) break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: - ShutterShow(); +// ShutterShow(); break; #endif // USE_WEBSERVER case FUNC_ACTIVE: diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index a6d1d0da0..3602b18d7 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -1978,7 +1978,7 @@ bool Xdrv27(uint32_t function) break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: - ShutterShow(); +// ShutterShow(); break; #endif // USE_WEBSERVER case FUNC_ACTIVE: diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index ce0e6740d..c98bc46d6 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -300,11 +300,11 @@ struct DALI { uint8_t last_dimmer; uint8_t dimmer[DALI_MAX_STORED]; uint8_t web_dimmer[DALI_MAX_STORED]; + uint8_t web_update[DALI_MAX_STORED]; uint8_t target; bool allow_light; bool last_power; bool power[DALI_MAX_STORED]; - bool web_power[DALI_MAX_STORED]; bool available; bool response; bool light_sync; @@ -783,7 +783,7 @@ uint32_t DaliCommission(uint8_t init_arg) { #ifdef USE_LIGHT DaliInitLight(); - uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address() : DALI_BROADCAST_DP; + uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address() : DALI_BROADCAST_DP; // DaliLight 1 DaliSendData(address, Dali->power[0]); // Restore lights #else DaliSendData(DALI_BROADCAST_DP, Dali->power[0]); // Restore lights @@ -912,8 +912,8 @@ bool DaliInit(uint32_t function) { Dali->allow_light = (FUNC_MODULE_INIT == function); // Light control is possible - AddLog(LOG_LEVEL_INFO, PSTR("DLI: GPIO%d(RX%s) and GPIO%d(TX%s)"), - Dali->pin_rx, (Dali->invert_rx)?"i":"", Dali->pin_tx, (Dali->invert_tx)?"i":""); + AddLog(LOG_LEVEL_INFO, PSTR("DLI: GPIO%d(RX%s) and GPIO%d(TX%s)%s"), + Dali->pin_rx, (Dali->invert_rx)?"i":"", Dali->pin_tx, (Dali->invert_tx)?"i":"", (Dali->allow_light)?" as light":""); pinMode(Dali->pin_tx, OUTPUT); digitalWrite(Dali->pin_tx, (Dali->invert_tx) ? LOW : HIGH); // Idle @@ -1221,10 +1221,10 @@ void CmndDaliLight(void) { // DaliLight 0 - Disable light controls // DaliLight 1 - Enable light controls if (Dali->allow_light && (XdrvMailbox.data_len > 0)) { - Settings->sbflag1.dali_light = XdrvMailbox.payload &1; + Settings->sbflag1.dali_light = XdrvMailbox.payload &1; // DaliLight 0/1 TasmotaGlobal.restart_flag = 2; // Restart to update GUI } - ResponseCmndStateText(Settings->sbflag1.dali_light); + ResponseCmndStateText(Settings->sbflag1.dali_light); // DaliLight 0/1 } #endif // USE_LIGHT @@ -1243,12 +1243,11 @@ const char HTTP_MSG_SLIDER_DALI[] PROGMEM = void DaliWebAddMainSlider(void) { WSContentSend_P(HTTP_TABLE100); char number[12]; - for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { + for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { // DaliLight 0/1, DaliGroupSliders Dali->web_dimmer[i] = Dali->dimmer[i]; - Dali->web_power[i] = Dali->power[i]; WSContentSend_P(HTTP_MSG_SLIDER_DALI, // Brightness - Black to White i, // k75 - WebColor((Dali->web_power[i])?COL_BUTTON:COL_BACKGROUND), + WebColor((Dali->power[i]) ? COL_BUTTON : COL_FORM), i, // k75= (0==i)?"B":"G", // B (Broadcast) or G1 to G16 (Group) (0==i)?"":itoa(i, number, 10), @@ -1266,7 +1265,7 @@ void DaliWebGetArg(void) { char webindex[8]; // WebGetArg name uint32_t index; - for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { + for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { // DaliLight 0/1, DaliGroupSliders snprintf_P(webindex, sizeof(webindex), PSTR("i75%d"), i); WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent if (strlen(tmp)) { @@ -1292,22 +1291,24 @@ void DaliShow(bool json) { ResponseAppendDali(0); #ifdef USE_WEBSERVER } else { - for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { - if (Dali->power[i] != Dali->web_power[i]) { - Dali->web_power[i] = Dali->power[i]; - WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""), - i, WebColor((Dali->web_power[i])?COL_BUTTON:COL_BACKGROUND)); - WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) - } + WSContentSend_P(PSTR("
")); // Terminate current {t} + WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { // DaliLight 0/1, DaliGroupSliders + WSContentSend_P(PSTR("eb('k75%d').style='background:#%06x';"), + i, WebColor((Dali->power[i]) ? COL_BUTTON : COL_FORM)); if (Dali->dimmer[i] != Dali->web_dimmer[i]) { - Dali->web_dimmer[i] = Dali->dimmer[i]; - WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""), - i, changeUIntScale(Dali->web_dimmer[i], 0, 254, 0, 100)); - WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) + Dali->web_update[i]++; + if (Dali->web_update[i] > 2) { // Allow two other users screen sync + Dali->web_update[i] = 0; + Dali->web_dimmer[i] = Dali->dimmer[i]; + } + WSContentSend_P(PSTR("eb('i75%d').value='%d';"), + i, changeUIntScale(Dali->dimmer[i], 0, 254, 0, 100)); + } } + WSContentSend_P(PSTR("\">{t}")); // Restart {t} = + WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) #endif // USE_WEBSERVER } } From a97aeeedb73c6ff60fc9351bf39054f14e7014af Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 10 Nov 2024 12:46:56 +0100 Subject: [PATCH 099/205] Add Tuya support --- tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino | 3 +-- tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino index 9e8e4d462..519a5fa0e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino @@ -1623,10 +1623,9 @@ void TuyaSensorsShow(bool json) void TuyaAddButton(void) { if (AsModuleTuyaMS()) { WSContentSend_P(HTTP_TABLE100); - WSContentSend_P(PSTR("
")); char stemp[33]; snprintf_P(stemp, sizeof(stemp), PSTR("" D_JSON_IRHVAC_MODE "")); - WSContentSend_P(HTTP_DEVICE_CONTROL, 26, TasmotaGlobal.devices_present + 1, + WSContentSend_P(HTTP_DEVICE_CONTROL, 26, TasmotaGlobal.devices_present + 1, TasmotaGlobal.devices_present + 1, (strlen(GetWebButton(TasmotaGlobal.devices_present))) ? HtmlEscape(GetWebButton(TasmotaGlobal.devices_present)).c_str() : stemp, ""); WSContentSend_P(PSTR("
")); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino index 9d4364552..58eec8637 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino @@ -2416,10 +2416,9 @@ void TuyaSensorsShow(bool json) void TuyaAddButton(void) { if (AsModuleTuyaMS()) { WSContentSend_P(HTTP_TABLE100); - WSContentSend_P(PSTR("
")); char stemp[33]; snprintf_P(stemp, sizeof(stemp), PSTR("" D_JSON_IRHVAC_MODE "")); - WSContentSend_P(HTTP_DEVICE_CONTROL, 26, TasmotaGlobal.devices_present + 1, + WSContentSend_P(HTTP_DEVICE_CONTROL, 26, TasmotaGlobal.devices_present + 1, TasmotaGlobal.devices_present + 1, (strlen(GetWebButton(TasmotaGlobal.devices_present))) ? HtmlEscape(GetWebButton(TasmotaGlobal.devices_present)).c_str() : stemp, ""); WSContentSend_P(PSTR("")); } From fd7554d96e932bef843892a310e739e67beeb807 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:28:25 +0100 Subject: [PATCH 100/205] Reduce minimal by 1k --- .../xdrv_01_9_webserver.ino | 35 +++++++++++-------- .../xdrv_27_esp32_shutter.ino | 13 ------- .../tasmota_xdrv_driver/xdrv_27_shutter.ino | 12 ------- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 15 +++++--- 4 files changed, 31 insertions(+), 44 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 69272c8da..de23ea46c 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -273,6 +273,7 @@ const char HTTP_MSG_SLIDER_GRADIENT[] PROGMEM = "" ""; +// https://stackoverflow.com/questions/4057236/how-to-add-onload-event-to-a-div-element const char HTTP_MSG_EXEC_JAVASCRIPT[] PROGMEM = ""; -//const char HTTP_DEVICE_CONTROL[] PROGMEM = ""; // ?o is related to WebGetArg(PSTR("o"), tmp, sizeof(tmp)) -//const char HTTP_DEVICE_CONTROL[] PROGMEM = ""; // ?o is related to WebGetArg(PSTR("o"), tmp, sizeof(tmp)) const char HTTP_DEVICE_CONTROL[] PROGMEM = ""; // ?o is related to WebGetArg(PSTR("o"), tmp, sizeof(tmp)) - const char HTTP_DEVICE_STATE[] PROGMEM = "%s"; enum ButtonTitle { @@ -467,9 +465,9 @@ ESP8266WebServer *Webserver; struct WEB { String chunk_buffer = ""; // Could be max 2 * CHUNKED_BUFFER_SIZE uint32_t upload_size = 0; + uint32_t slider_update_time = 0; int slider[LST_MAX]; uint16_t upload_error = 0; - uint8_t slider_update[LST_MAX]; uint8_t state = HTTP_OFF; uint8_t upload_file_type; uint8_t config_block_count = 0; @@ -608,7 +606,6 @@ void StartWebserver(int type) for (uint32_t i = 0; i < LST_MAX; i++) { Web.slider[i] = -1; - Web.slider_update[i] = 0; } if (!Webserver) { @@ -1234,8 +1231,11 @@ void HandleRoot(void) { #endif WSContentSend_P(HTTP_SCRIPT_ROOT_PART2); WSContentSendStyle(); + WSContentSend_P(PSTR("
")); +#ifndef FIRMWARE_MINIMAL + if (TasmotaGlobal.devices_present) { uint32_t buttons_non_light = TasmotaGlobal.devices_present; uint32_t button_idx = 1; @@ -1252,8 +1252,7 @@ void HandleRoot(void) { #ifdef USE_SHUTTER // Chk for reduced toggle buttons used by shutters - uint32_t shutter_button = 0; // Bitmask for each button - + uint32_t shutter_button = 0; // Bitmask for each button // Find and skip dedicated shutter buttons if (buttons_non_light && Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support for (button_idx = 1; button_idx <= buttons_non_light; button_idx++) { @@ -1265,9 +1264,9 @@ void HandleRoot(void) { } #endif // USE_SHUTTER - if (buttons_non_light_non_shutter) { // Any non light AND non shutter button + if (buttons_non_light_non_shutter) { // Any non light AND non shutter button // Display toggle buttons - WSContentSend_P(HTTP_TABLE100); // "" + WSContentSend_P(HTTP_TABLE100); // "
" WSContentSend_P(PSTR("")); #ifdef USE_SONOFF_IFAN @@ -1517,7 +1516,6 @@ void HandleRoot(void) { } WSContentSend_P(PSTR("")); -#ifndef FIRMWARE_MINIMAL XdrvXsnsCall(FUNC_WEB_ADD_MAIN_BUTTON); #endif // Not FIRMWARE_MINIMAL @@ -1558,6 +1556,8 @@ bool HandleRootStatusRefresh(void) return false; } +#ifndef FIRMWARE_MINIMAL + #ifdef USE_SCRIPT_WEB_DISPLAY Script_Check_HTML_Setvars(); #endif @@ -1727,6 +1727,7 @@ bool HandleRootStatusRefresh(void) uint16_t hue; uint8_t sat; int current_value = -1; + uint32_t slider_update_time = millis(); for (uint32_t i = 0; i < LST_MAX; i++) { if (Web.slider[i] != -1) { if (!Settings->flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM @@ -1750,12 +1751,13 @@ bool HandleRootStatusRefresh(void) current_value = changeUIntScale(Settings->light_color[i], 0, 255, 0, 100); } if (current_value != Web.slider[i]) { - Web.slider_update[i]++; - if (Web.slider_update[i] > 2) { // Allow two other users screen sync - Web.slider_update[i] = 0; + if (0 == Web.slider_update_time) { + Web.slider_update_time = slider_update_time + Settings->web_refresh; // Allow other users to sync screen + } + else if (slider_update_time > Web.slider_update_time) { + Web.slider_update_time = 1; // Allow multiple updates Web.slider[i] = current_value; } - // https://stackoverflow.com/questions/4057236/how-to-add-onload-event-to-a-div-element if (!msg_exec_javascript) { WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "shutter_options[i] & 1) ? D_OPEN : D_CLOSE,(Settings->shutter_options[i] & 1) ? D_CLOSE : D_OPEN, (Settings->shutter_options[i] & 1) ? (100 - ShutterRealToPercentPosition(-9999, i)) : ShutterRealToPercentPosition(-9999, i), i+1); - WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) - } -} - /*********************************************************************************************\ * Commands \*********************************************************************************************/ @@ -1976,11 +1969,6 @@ bool Xdrv27(uint32_t function) result = true; } break; -#ifdef USE_WEBSERVER - case FUNC_WEB_SENSOR: -// ShutterShow(); - break; -#endif // USE_WEBSERVER case FUNC_ACTIVE: result = true; break; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index c98bc46d6..d56f22e4e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -292,6 +292,7 @@ struct DALI { uint32_t bit_cycles; uint32_t last_activity; uint32_t received_dali_data; // Data received from DALI bus + uint32_t slider_update_time; uint8_t pin_rx; uint8_t pin_tx; uint8_t max_short_address; @@ -300,7 +301,6 @@ struct DALI { uint8_t last_dimmer; uint8_t dimmer[DALI_MAX_STORED]; uint8_t web_dimmer[DALI_MAX_STORED]; - uint8_t web_update[DALI_MAX_STORED]; uint8_t target; bool allow_light; bool last_power; @@ -1293,20 +1293,25 @@ void DaliShow(bool json) { } else { WSContentSend_P(PSTR("
")); // Terminate current {t} WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { // DaliLight 0/1, DaliGroupSliders WSContentSend_P(PSTR("eb('k75%d').style='background:#%06x';"), i, WebColor((Dali->power[i]) ? COL_BUTTON : COL_FORM)); if (Dali->dimmer[i] != Dali->web_dimmer[i]) { - Dali->web_update[i]++; - if (Dali->web_update[i] > 2) { // Allow two other users screen sync - Dali->web_update[i] = 0; + if (0 == Dali->slider_update_time) { + Dali->slider_update_time = slider_update_time + Settings->web_refresh; // Allow other users to sync screen + } + else if (slider_update_time > Dali->slider_update_time) { + Dali->slider_update_time = 1; // Allow multiple updates Dali->web_dimmer[i] = Dali->dimmer[i]; } WSContentSend_P(PSTR("eb('i75%d').value='%d';"), i, changeUIntScale(Dali->dimmer[i], 0, 254, 0, 100)); - } } + if (1 == Dali->slider_update_time) { + Dali->slider_update_time = 0; + } WSContentSend_P(PSTR("\">{t}")); // Restart {t} = WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) #endif // USE_WEBSERVER From 5f9912665adabc7597bca69cfa52416f3cea6ec6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 10 Nov 2024 17:40:03 +0100 Subject: [PATCH 101/205] Clean Tuya code --- .../xdrv_01_9_webserver.ino | 16 ------------- .../xdrv_16_tuyamcu_v1.ino | 24 ++++++++++++++++--- .../xdrv_16_tuyamcu_v2.ino | 24 ++++++++++++++++--- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index de23ea46c..888f7f8fd 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1580,19 +1580,6 @@ bool HandleRootStatusRefresh(void) } } else { #endif // USE_SONOFF_IFAN -#ifdef USE_TUYA_MCU - if (IsModuleTuya()) { - if (device <= TasmotaGlobal.devices_present) { - ExecuteCommandPower(device, POWER_TOGGLE, SRC_IGNORE); - } else { - if (AsModuleTuyaMS() && device == TasmotaGlobal.devices_present + 1) { - uint8_t dpId = TuyaGetDpId(TUYA_MCU_FUNC_MODESET); - snprintf_P(svalue, sizeof(svalue), PSTR("Tuyasend4 %d,%d"), dpId, !TuyaModeSet()); - ExecuteCommand(svalue, SRC_WEBGUI); - } - } - } else { -#endif // USE_TUYA_MCU #ifdef USE_SHUTTER int32_t ShutterWebButton; if (ShutterWebButton = IsShutterWebButton(device)) { @@ -1607,9 +1594,6 @@ bool HandleRootStatusRefresh(void) #ifdef USE_SONOFF_IFAN } #endif // USE_SONOFF_IFAN -#ifdef USE_TUYA_MCU - } -#endif // USE_TUYA_MCU } #ifdef USE_LIGHT WebGetArg(PSTR("d0"), tmp, sizeof(tmp)); // 0 - 100 Dimmer value diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino index 519a5fa0e..869bf6141 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino @@ -1620,17 +1620,32 @@ void TuyaSensorsShow(bool json) #ifdef USE_WEBSERVER +#define WEB_HANDLE_TUYA "d16" + void TuyaAddButton(void) { if (AsModuleTuyaMS()) { WSContentSend_P(HTTP_TABLE100); char stemp[33]; - snprintf_P(stemp, sizeof(stemp), PSTR("" D_JSON_IRHVAC_MODE "")); - WSContentSend_P(HTTP_DEVICE_CONTROL, 26, TasmotaGlobal.devices_present + 1, TasmotaGlobal.devices_present + 1, - (strlen(GetWebButton(TasmotaGlobal.devices_present))) ? HtmlEscape(GetWebButton(TasmotaGlobal.devices_present)).c_str() : stemp, ""); + snprintf_P(stemp, sizeof(stemp), PSTR(D_JSON_IRHVAC_MODE)); + WSContentSend_P(PSTR(""), // &d16 is related to WebGetArg("d16", tmp, sizeof(tmp)); + (strlen(GetWebButton(TasmotaGlobal.devices_present))) ? HtmlEscape(GetWebButton(TasmotaGlobal.devices_present)).c_str() : stemp); WSContentSend_P(PSTR("
")); } } +void TuyaWebGetArg(void) { + if (AsModuleTuyaMS()) { + char tmp[8]; // WebGetArg numbers only + WebGetArg(PSTR(WEB_HANDLE_TUYA), tmp, sizeof(tmp)); + if (strlen(tmp)) { + uint8_t dpId = TuyaGetDpId(TUYA_MCU_FUNC_MODESET); + char svalue[32]; + snprintf_P(svalue, sizeof(svalue), PSTR("Tuyasend4 %d,%d"), dpId, !TuyaModeSet()); + ExecuteWebCommand(svalue); + } + } +} + #endif // USE_WEBSERVER /*********************************************************************************************\ @@ -1723,6 +1738,9 @@ bool Xdrv16(uint32_t function) { case FUNC_WEB_ADD_MAIN_BUTTON: TuyaAddButton(); break; + case FUNC_WEB_GET_ARG: + TuyaWebGetArg(); + break; case FUNC_WEB_SENSOR: TuyaSensorsShow(0); break; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino index 58eec8637..31b47e286 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino @@ -2413,17 +2413,32 @@ void TuyaSensorsShow(bool json) #ifdef USE_WEBSERVER +#define WEB_HANDLE_TUYA "d16" + void TuyaAddButton(void) { if (AsModuleTuyaMS()) { WSContentSend_P(HTTP_TABLE100); char stemp[33]; - snprintf_P(stemp, sizeof(stemp), PSTR("" D_JSON_IRHVAC_MODE "")); - WSContentSend_P(HTTP_DEVICE_CONTROL, 26, TasmotaGlobal.devices_present + 1, TasmotaGlobal.devices_present + 1, - (strlen(GetWebButton(TasmotaGlobal.devices_present))) ? HtmlEscape(GetWebButton(TasmotaGlobal.devices_present)).c_str() : stemp, ""); + snprintf_P(stemp, sizeof(stemp), PSTR(D_JSON_IRHVAC_MODE)); + WSContentSend_P(PSTR(""), // &d16 is related to WebGetArg("d16", tmp, sizeof(tmp)); + (strlen(GetWebButton(TasmotaGlobal.devices_present))) ? HtmlEscape(GetWebButton(TasmotaGlobal.devices_present)).c_str() : stemp); WSContentSend_P(PSTR("")); } } +void TuyaWebGetArg(void) { + if (AsModuleTuyaMS()) { + char tmp[8]; // WebGetArg numbers only + WebGetArg(PSTR(WEB_HANDLE_TUYA), tmp, sizeof(tmp)); + if (strlen(tmp)) { + uint8_t dpId = TuyaGetDpId(TUYA_MCU_FUNC_MODESET); + char svalue[32]; + snprintf_P(svalue, sizeof(svalue), PSTR("Tuyasend4 %d,%d"), dpId, !TuyaModeSet()); + ExecuteWebCommand(svalue); + } + } +} + #endif // USE_WEBSERVER /*********************************************************************************************\ @@ -2558,6 +2573,9 @@ bool Xdrv16(uint32_t function) { case FUNC_WEB_ADD_MAIN_BUTTON: TuyaAddButton(); break; + case FUNC_WEB_GET_ARG: + TuyaWebGetArg(); + break; case FUNC_WEB_SENSOR: TuyaSensorsShow(0); break; From 448ca1c1096239400f438abc37b6ac8ce2590792 Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Sun, 10 Nov 2024 23:23:37 +0100 Subject: [PATCH 102/205] MI32 legacy: add config operations (#22458) --- .../esp-nimble-cpp/src/NimBLEDevice.cpp | 11 ++--- .../tasmota_xsns_sensor/xsns_62_esp32_mi.ino | 44 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.cpp b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.cpp index d14ce62d7..817f3c3a3 100644 --- a/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.cpp +++ b/lib/libesp32_div/esp-nimble-cpp/src/NimBLEDevice.cpp @@ -444,12 +444,13 @@ int NimBLEDevice::getPower() { */ /* STATIC*/ NimBLEAddress NimBLEDevice::getAddress() { - ble_addr_t addr = {BLE_ADDR_PUBLIC, 0}; + ble_addr_t addr = {m_own_addr_type, 0}; - if(BLE_HS_ENOADDR == ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)) { - NIMBLE_LOGD(LOG_TAG, "Public address not found, checking random"); - addr.type = BLE_ADDR_RANDOM; - ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL); + if(BLE_HS_ENOADDR == ble_hs_id_copy_addr(m_own_addr_type, addr.val, NULL)) { + // NIMBLE_LOGD(LOG_TAG, "Public address not found, checking random"); + // addr.type = BLE_ADDR_RANDOM; + // ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL); + return NimBLEAddress(); // return blank to report error } return NimBLEAddress(addr); diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino index f0d816744..34432ff48 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino @@ -66,6 +66,7 @@ #include #include "include/xsns_62_esp32_mi.h" +#include "services/gap/ble_svc_gap.h" void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify); void MI32AddKey(mi_bindKey_t keyMAC); @@ -732,7 +733,50 @@ extern "C" { MI32BLELoop(); } + bool MI32runBerryConfig(uint16_t operation){ + bool success = false; + #ifdef CONFIG_BT_NIMBLE_EXT_ADV + NimBLEExtAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); + #else + NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); + #endif + if(pAdvertising == nullptr){ + return success; + } + switch(operation){ + case 231: // set address + pAdvertising->stop(); + if(MI32.conCtx->addrType > 0){ + ble_hs_id_set_rnd(MI32.conCtx->MAC); + AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: set MAC to random")); + } + NimBLEDevice::setOwnAddrType(MI32.conCtx->addrType); + success = true; + break; + case 232: // set adv params via bytes() descriptor of size 5, + if(MI32.conCtx->buffer[0] == 5){ + uint16_t itvl_min = MI32.conCtx->buffer[2] + (MI32.conCtx->buffer[3] << 8); + uint16_t itvl_max = MI32.conCtx->buffer[4] + (MI32.conCtx->buffer[5] << 8); + pAdvertising->setAdvertisementType(MI32.conCtx->buffer[1]); + pAdvertising->setMinInterval(itvl_min); + pAdvertising->setMaxInterval(itvl_max); + AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: adv params: type: %u, min: %u, max: %u"),MI32.conCtx->buffer[1], (uint16_t)(itvl_min * 0.625), (uint16_t)(itvl_max * 0.625)) ; + success = true; + } + break; + case 233: + int ret = ble_svc_gap_device_name_set((const char*)MI32.conCtx->buffer + 1); + AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: new gap device name - %s"),(const char*) MI32.conCtx->buffer + 1); + success = (ret == 0); + break; + } + return success; + } + bool MI32runBerryServer(uint16_t operation){ + if(operation > 230){ + return MI32runBerryConfig(operation); + } MI32.conCtx->operation = operation; AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: Berry server op: %d, response: %u"),MI32.conCtx->operation, MI32.conCtx->response); if(MI32.mode.readyForNextServerJob == 0){ From 343d9b9758b21da2e139982750d3283b2e667989 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Mon, 11 Nov 2024 10:39:18 +0100 Subject: [PATCH 103/205] Remove logging from safeboot (#22464) * Remove logging from safeboot * Remove logs from Status 5 --- tasmota/tasmota_support/support_a_spi.ino | 2 ++ tasmota/tasmota_support/support_command.ino | 2 ++ tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino | 8 ++++++++ 3 files changed, 12 insertions(+) diff --git a/tasmota/tasmota_support/support_a_spi.ino b/tasmota/tasmota_support/support_a_spi.ino index 35a3db4b0..b3a7f915b 100644 --- a/tasmota/tasmota_support/support_a_spi.ino +++ b/tasmota/tasmota_support/support_a_spi.ino @@ -43,6 +43,7 @@ SPIClass *SpiBegin(uint32 bus) { /********************************************************************************************/ void AddLogSpi(uint32_t hardware, int clk, int mosi, int miso) { +#ifndef FIRMWARE_MINIMAL uint32_t enabled = TasmotaGlobal.soft_spi_enabled; char hwswbus[8]; if (hardware) { @@ -72,4 +73,5 @@ void AddLogSpi(uint32_t hardware, int clk, int mosi, int miso) { hwswbus, clk, mosi, miso); break; } +#endif // FIRMWARE_MINIMAL } diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 9235f8ea6..cef08e1c4 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -956,7 +956,9 @@ void CmndStatus(void) if ((0 == payload) || (5 == payload)) { #ifdef USE_IPV6 +#ifndef FIRMWARE_MINIMAL if (5 == payload) { WifiDumpAddressesIPv6(); } +#endif // FIRMWARE_MINIMAL Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "1\":\"%s\",\"" D_JSON_DNSSERVER "2\":\"%s\",\"" diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index a9e7ed17c..6a40129ef 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -168,10 +168,12 @@ void EthernetEvent(arduino_event_t *event) { } TasmotaGlobal.rules_flag.eth_connected = 1; TasmotaGlobal.global_state.eth_down = 0; +#ifndef FIRMWARE_MINIMAL AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: IPv4 %_I, mask %_I, gateway %_I"), event->event_info.got_ip.ip_info.ip.addr, event->event_info.got_ip.ip_info.netmask.addr, event->event_info.got_ip.ip_info.gw.addr); +#endif // FIRMWARE_MINIMAL WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use break; @@ -181,9 +183,11 @@ void EthernetEvent(arduino_event_t *event) { ip_addr_t ip_addr6; ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); IPAddress addr(&ip_addr6); +#ifndef FIRMWARE_MINIMAL AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"), event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", IPv6isLocal(addr) ? PSTR("Local") : PSTR("Global"), addr.toString().c_str()); +#endif // FIRMWARE_MINIMAL if (!IPv6isLocal(addr)) { // declare network up on IPv6 TasmotaGlobal.rules_flag.eth_connected = 1; TasmotaGlobal.global_state.eth_down = 0; @@ -235,13 +239,17 @@ void EthernetInit(void) { if (eth_uses_spi) { // Uses SPI Ethernet and needs at least SPI CS being ETH MDC if (!PinUsed(GPIO_ETH_PHY_MDC)) { +#ifndef FIRMWARE_MINIMAL AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ETH "No ETH MDC as SPI CS GPIO defined")); +#endif // FIRMWARE_MINIMAL return; } } else { // Native ESP32 if (!PinUsed(GPIO_ETH_PHY_MDC) && !PinUsed(GPIO_ETH_PHY_MDIO)) { // && should be || but keep for backward compatibility +#ifndef FIRMWARE_MINIMAL AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ETH "No ETH MDC and ETH MDIO GPIO defined")); +#endif // FIRMWARE_MINIMAL return; } } From c86f74d456663f021fc6b91cd5ebb61cd94b923b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 13:34:09 +0100 Subject: [PATCH 104/205] Bump version v14.3.0.5 - Redesign GUI adding feedback to buttons, shutters and lights --- CHANGELOG.md | 19 ++++++++++++++----- RELEASENOTES.md | 4 ++-- tasmota/include/tasmota_types.h | 2 +- tasmota/include/tasmota_version.h | 2 +- tools/decode-status.py | 4 ++-- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01fe6b01c..5e9e07e98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,20 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.3.0.4] +## [14.3.0.5] +### Added + +### Breaking Changed + +### Changed +- Redesign GUI adding feedback to buttons, shutters and lights + +### Fixed + +### Removed +- Command ``SetOption161 1`` to disable web page slider updates by commands + +## [14.3.0.4] 20241111 ### Added - DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight` - Support for I2C over Serial (#22444) @@ -13,8 +26,6 @@ All notable changes to this project will be documented in this file. - Berry add I2C read16/write16 supporting Little Endian (#22448) - Berry drivers for PCA9535 (generic and in SenseCAP D1) (#22451) -### Breaking Changed - ### Changed - AHT1X/AHT2X/AHT3X ready for virtual I2C (#22427) - SGP4X ready for virtual I2C (#22427) @@ -28,8 +39,6 @@ All notable changes to this project will be documented in this file. - FUNC_COMMAND linked list command buffer corruption by shutter driver - ESP32, ESP32-S2 and ESP32-S3 re-enable touch buttons (#22446) -### Removed - ## [14.3.0.3] 20241031 ### Added - Support for I2C over Serial, preliminary stub (#22388) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index fe1fede6a..9ddc2ba5f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -114,9 +114,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.3.0.4 +## Changelog v14.3.0.5 ### Added -- Command ``SetOption161 1`` to disable web page slider updates by commands - DALI support for short addresses (gear) and groups - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups @@ -146,6 +145,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Changed - ESP32 Platform from 2024.09.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241030 and IDF to 5.3.1.241024 [#22384](https://github.com/arendst/Tasmota/issues/22384) - ESP32 LVGL library from v9.2.0 to v9.2.2 [#22385](https://github.com/arendst/Tasmota/issues/22385) +- Redesign GUI adding feedback to buttons, shutters and lights - Unit (k)VAr(h) to (k)var(h) [#22435](https://github.com/arendst/Tasmota/issues/22435) - AHT1X/AHT2X/AHT3X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) - SGP4X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index 8752a6ec8..ceeb9cc8d 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -195,7 +195,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t mqtt_disable_modbus : 1; // bit 12 (v13.3.0.5) - SetOption158 - (MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead uint32_t counter_both_edges : 1; // bit 13 (v13.3.0.5) - SetOption159 - (Counter) Enable counting on both rising and falling edge (1) uint32_t ld2410_use_pin : 1; // bit 14 (v14.3.0.2) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1) - uint32_t disable_slider_updates : 1; // bit 15 (v14.3.0.2) - SetOption161 - (Light) Disable slider updates by commands (1) + uint32_t spare15 : 1; // bit 15 uint32_t spare16 : 1; // bit 16 uint32_t spare17 : 1; // bit 17 uint32_t spare18 : 1; // bit 18 diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index d49cbe725..78cccdb21 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E030004; // 14.3.0.4 +const uint32_t TASMOTA_VERSION = 0x0E030005; // 14.3.0.5 #endif // _TASMOTA_VERSION_H_ diff --git a/tools/decode-status.py b/tools/decode-status.py index 116c09a95..dd487a206 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -216,7 +216,7 @@ a_setoption = [[ "(MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead", "(Counter) Enable counting on both rising and falling edge (1)", "(LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1)", - "(Light) Disable slider updates by commands (1)", + "", "","","","", "","","","", "","","","", @@ -340,7 +340,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v14.3.0.2 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v14.3.0.5 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 0536cc87a075035767c4720c575aecf17e391cba Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 13:39:50 +0100 Subject: [PATCH 105/205] Update changelogs --- BUILDS.md | 2 +- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/BUILDS.md b/BUILDS.md index b8f12a5f6..91294c5e1 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -283,7 +283,7 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the | USE_SONOFF_SPM | | / x | | | | | | USE_DISPLAY_TM1621_SONOFF | | / x | | | | | | USE_SHELLY_PRO | | / x | | | | | -| USE_DALI | | / - | | | | | +| USE_DALI | | / x | | | | | | USE_DINGTIAN_RELAY | | / - | | | | | | USE_MATTER_DEVICE | | / x | | | | | See SetOption151 | diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e9e07e98..a95390c19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ## [14.3.0.5] ### Added +- ESP32 MI32 legacy add config operations (#22458) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 9ddc2ba5f..efa1111c5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -135,6 +135,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC [#22370](https://github.com/arendst/Tasmota/issues/22370) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) +- ESP32 MI32 legacy add config operations [#22458](https://github.com/arendst/Tasmota/issues/22458) - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) - Berry add I2C read16/write16 supporting Little Endian [#22448](https://github.com/arendst/Tasmota/issues/22448) - Berry drivers for PCA9535 (generic and in SenseCAP D1) [#22451](https://github.com/arendst/Tasmota/issues/22451) From 0744bf7f2b4c03ac85fb4b121de661cb5db651de Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:17:22 +0100 Subject: [PATCH 106/205] Save 6k code from ESP32 safeboot --- tasmota/tasmota_support/settings.ino | 4 +- .../xdrv_01_9_webserver.ino | 47 +++++++------------ .../tasmota_xdrv_driver/xdrv_06_snfbridge.ino | 4 ++ .../xdrv_16_tuyamcu_v1.ino | 4 ++ .../xdrv_16_tuyamcu_v2.ino | 4 ++ .../tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino | 4 ++ 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index c509f5cba..09376bb05 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -687,9 +687,11 @@ char* SettingsText(uint32_t index) { if (index >= SET_MAX) { // Index above SET_MAX are not stored in Settings #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL if (SET_BUTTON17 <= index && index <= SET_BUTTON32) return (char*)GetWebButton(index-SET_BUTTON17+16); -#endif +#endif // not FIRMWARE_MINIMAL +#endif // USE_WEBSERVER position += settings_text_size -1; // Setting not supported - internal error - return empty string } else { SettingsUpdateFinished(); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 888f7f8fd..a7c391b81 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -582,10 +582,8 @@ const WebServerDispatch_t WebServerDispatch[] PROGMEM = { { "dl", HTTP_ANY, HandleBackupConfiguration }, { "rs", HTTP_ANY, HandleRestoreConfiguration }, { "rt", HTTP_ANY, HandleResetConfiguration }, + { "in", HTTP_ANY, HandleInformation } #endif // Not FIRMWARE_MINIMAL -#ifndef FIRMWARE_MINIMAL_ONLY - { "in", HTTP_ANY, HandleInformation }, -#endif // Not FIRMWARE_MINIMAL_ONLY }; void WebServer_on(const char * prefix, void (*func)(void), uint8_t method = HTTP_ANY) { @@ -1521,14 +1519,7 @@ void HandleRoot(void) { if (HTTP_ADMIN == Web.state) { #ifdef FIRMWARE_MINIMAL -#ifdef ESP32 -#ifndef FIRMWARE_MINIMAL_ONLY - WSContentSpaceButton(BUTTON_INFORMATION); - WSContentButton(BUTTON_FIRMWARE_UPGRADE); -#endif // FIRMWARE_MINIMAL_ONLY -#else // ESP8266 WSContentSpaceButton(BUTTON_FIRMWARE_UPGRADE); -#endif // ESP32 WSContentButton(BUTTON_CONSOLE); #else // Not FIRMWARE_MINIMAL WSContentSpaceButton(BUTTON_CONFIGURATION); @@ -1912,7 +1903,7 @@ void HandleTemplateConfiguration(void) { if (!FlashPin(i)) { WSContentSend_P(PSTR("%s%d"), (i>0)?",":"", template_gp.io[i]); } -#endif +#endif // CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 } WSContentSend_P(PSTR("}1%d}1%d"), flag, Settings->user_template_base); // FLAG: 1 BASE: 17 WSContentEnd(); @@ -1966,7 +1957,7 @@ void HandleTemplateConfiguration(void) { RedPin(i) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? PSTR(" style='width:146px'") : "", i, i); WSContentSend_P(PSTR(""), i); } -#endif +#endif // CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 } WSContentSend_P(PSTR("")); @@ -2202,7 +2193,7 @@ void HandleWifiConfiguration(void) { WebRestart(3); #else HandleRoot(); -#endif +#endif // RESTART_AFTER_INITIAL_WIFI_CONFIG } } @@ -2365,7 +2356,7 @@ void HandleWifiConfiguration(void) { WSContentSend_P(HTTP_FORM_WIFI_PART2, SettingsTextEscaped(SET_STASSID2).c_str(), WIFI_HOSTNAME, WIFI_HOSTNAME, SettingsTextEscaped(SET_HOSTNAME).c_str(), SettingsTextEscaped(SET_CORS).c_str()); #else WSContentSend_P(HTTP_FORM_WIFI_PART2, SettingsTextEscaped(SET_STASSID2).c_str(), WIFI_HOSTNAME, WIFI_HOSTNAME, SettingsTextEscaped(SET_HOSTNAME).c_str()); -#endif +#endif // USE_CORS } WSContentSend_P(HTTP_FORM_END); @@ -2400,7 +2391,7 @@ void WifiSaveSettings(void) { cmnd += AddWebCommand(PSTR(D_CMND_HOSTNAME), PSTR("h"), PSTR("1")); #ifdef USE_CORS cmnd += AddWebCommand(PSTR(D_CMND_CORS), PSTR("c"), PSTR("1")); -#endif +#endif // USE_CORS cmnd += AddWebCommand(PSTR(D_CMND_SSID "1"), PSTR("s1"), PSTR("1")); cmnd += AddWebCommand(PSTR(D_CMND_SSID "2"), PSTR("s2"), PSTR("1")); cmnd += AddWebCommand(PSTR(D_CMND_PASSWORD "3"), PSTR("p1"), PSTR("\"")); @@ -2617,12 +2608,6 @@ void HandleRestoreConfiguration(void) Web.upload_file_type = UPL_SETTINGS; } -#endif // Not FIRMWARE_MINIMAL - -/*-------------------------------------------------------------------------------------------*/ - -#ifndef FIRMWARE_MINIMAL_ONLY - void WSContentSeparatorI(uint32_t size) { WSContentSend_P(PSTR("
"), (1 == size)?" size=1":""); // WSContentSend_P(PSTR("
"), size); @@ -2873,7 +2858,8 @@ void HandleInformation(void) { WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); } -#endif // Not FIRMWARE_MINIMAL_ONLY + +#endif // Not FIRMWARE_MINIMAL /*-------------------------------------------------------------------------------------------*/ @@ -2939,7 +2925,7 @@ void HandleUpgradeFirmware(void) { } #else WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_START_UPGRADE)); -#endif +#endif // ESP32 WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); @@ -3169,7 +3155,7 @@ void HandleUploadLoop(void) { uint32_t upload_size = (!strlen(tmp)) ? 0 : atoi(tmp); AddLog(LOG_LEVEL_DEBUG, D_LOG_UPLOAD "Freespace %i Filesize %i", ESP.getFreeSketchSpace(), upload_size); if (upload_size > ESP.getFreeSketchSpace()) { // TODO revisit this test -#endif +#endif // ESP8266 Web.upload_error = 4; // Program flash size is larger than real flash size return; } @@ -3565,6 +3551,8 @@ bool CaptivePortal(void) /*********************************************************************************************/ +#ifndef FIRMWARE_MINIMAL + enum {QUERY_DEFAULT=0, QUERY_RUN}; int WebQuery(char *buffer, int query_function); @@ -3727,7 +3715,6 @@ int WebQuery(char *buffer, int query_function = 0) return status; } - int WebSend(char *buffer) { // [tasmota] POWER1 ON --> Sends http://tasmota/cm?cmnd=POWER1 ON @@ -3878,7 +3865,6 @@ const char kWebCmndStatus[] PROGMEM = D_JSON_DONE "|" D_JSON_WRONG_PARAMETERS "| const char kWebCommands[] PROGMEM = "|" // No prefix D_CMND_WEBLOG "|" -#ifndef FIRMWARE_MINIMAL_ONLY D_CMND_WEBTIME "|" #ifdef USE_EMULATION D_CMND_EMULATION "|" @@ -3897,12 +3883,10 @@ const char kWebCommands[] PROGMEM = "|" // No prefix #ifdef USE_CORS "|" D_CMND_CORS #endif -#endif // FIRMWARE_MINIMAL_ONLY ; void (* const WebCommand[])(void) PROGMEM = { &CmndWeblog, -#ifndef FIRMWARE_MINIMAL_ONLY &CmndWebTime, #ifdef USE_EMULATION &CmndEmulation, @@ -3921,7 +3905,6 @@ void (* const WebCommand[])(void) PROGMEM = { #ifdef USE_CORS , &CmndCors #endif -#endif // FIRMWARE_MINIMAL_ONLY }; /*********************************************************************************************/ @@ -4174,7 +4157,9 @@ void CmndCors(void) } ResponseCmndChar(SettingsText(SET_CORS)); } -#endif +#endif // USE_CORS + +#endif // not FIRMWARE_MINIMAL /*********************************************************************************************\ * Interface @@ -4263,9 +4248,11 @@ bool Xdrv01(uint32_t function) } } break; +#ifndef FIRMWARE_MINIMAL case FUNC_COMMAND: result = DecodeCommand(kWebCommands, WebCommand); break; +#endif // FIRMWARE_MINIMAL case FUNC_ACTIVE: result = true; break; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino index 19b5b728c..8bbaeef56 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino @@ -512,6 +512,7 @@ void CmndRfTimeout(void) { } #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL void SonoffBridgeAddButton(void) { WSContentSend_P(HTTP_TABLE100); @@ -539,6 +540,7 @@ void SonoffBridgeWebGetArg(void) { } } +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER /*********************************************************************************************\ @@ -559,12 +561,14 @@ bool Xdrv06(uint32_t function) result = DecodeCommand(kSonoffBridgeCommands, SonoffBridgeCommand); break; #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL case FUNC_WEB_ADD_MAIN_BUTTON: SonoffBridgeAddButton(); break; case FUNC_WEB_GET_ARG: SonoffBridgeWebGetArg(); break; +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER case FUNC_INIT: if (Settings->rf_duplicate_time < 10) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino index 869bf6141..d4ab71400 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino @@ -1619,6 +1619,7 @@ void TuyaSensorsShow(bool json) } #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL #define WEB_HANDLE_TUYA "d16" @@ -1646,6 +1647,7 @@ void TuyaWebGetArg(void) { } } +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER /*********************************************************************************************\ @@ -1735,6 +1737,7 @@ bool Xdrv16(uint32_t function) { TuyaSensorsShow(1); break; #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL case FUNC_WEB_ADD_MAIN_BUTTON: TuyaAddButton(); break; @@ -1744,6 +1747,7 @@ bool Xdrv16(uint32_t function) { case FUNC_WEB_SENSOR: TuyaSensorsShow(0); break; +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER case FUNC_ACTIVE: result = true; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino index 31b47e286..0684718e2 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino @@ -2412,6 +2412,7 @@ void TuyaSensorsShow(bool json) } #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL #define WEB_HANDLE_TUYA "d16" @@ -2439,6 +2440,7 @@ void TuyaWebGetArg(void) { } } +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER /*********************************************************************************************\ @@ -2570,6 +2572,7 @@ bool Xdrv16(uint32_t function) { TuyaSensorsShow(1); break; #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL case FUNC_WEB_ADD_MAIN_BUTTON: TuyaAddButton(); break; @@ -2579,6 +2582,7 @@ bool Xdrv16(uint32_t function) { case FUNC_WEB_SENSOR: TuyaSensorsShow(0); break; +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER case FUNC_ACTIVE: result = true; diff --git a/tasmota/tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino b/tasmota/tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino index 4270fc665..8bcefb940 100644 --- a/tasmota/tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino +++ b/tasmota/tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino @@ -246,6 +246,7 @@ void LscMcModuleSelected(void) { } #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL #ifdef USE_LSC_MCSL_GUI void LscMcAddFuctionButtons(void) { @@ -287,6 +288,7 @@ void LscMcWebGetArg(void) { } #endif // USE_LSC_MCSL_GUI +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER @@ -306,6 +308,7 @@ bool Xlgt07(uint32_t function) result = LscMcMultiButtonPressed(); break; #ifdef USE_WEBSERVER +#ifndef FIRMWARE_MINIMAL #ifdef USE_LSC_MCSL_GUI case FUNC_WEB_ADD_MAIN_BUTTON: LscMcAddFuctionButtons(); @@ -314,6 +317,7 @@ bool Xlgt07(uint32_t function) LscMcWebGetArg(); break; #endif // USE_LSC_MCSL_GUI +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER case FUNC_MODULE_INIT: LscMcModuleSelected(); From 1b9d206dd8410602453b382351d1610037be5825 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:23:21 +0100 Subject: [PATCH 107/205] save 28k for ESP32 safeboot --- tasmota/tasmota_support/support_command.ino | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index cef08e1c4..559e796c6 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -22,7 +22,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_SO_WIFINOSLEEP "|" // Other commands D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_RESTART "|" -#ifndef FIRMWARE_MINIMAL_ONLY +#ifndef FIRMWARE_MINIMAL D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_POWERLOCK "|" D_CMND_TIMEDPOWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_SLEEP "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|" D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_STATETEXT "|" D_CMND_SAVEDATA "|" D_CMND_SO "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|" D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" @@ -53,7 +53,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix #endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 D_CMND_CPU_FREQUENCY #endif // ESP32 -#endif //FIRMWARE_MINIMAL_ONLY +#endif //FIRMWARE_MINIMAL ; SO_SYNONYMS(kTasmotaSynonyms, @@ -62,7 +62,7 @@ SO_SYNONYMS(kTasmotaSynonyms, void (* const TasmotaCommand[])(void) PROGMEM = { &CmndUpgrade, &CmndUpgrade, &CmndOtaUrl, &CmndSeriallog, &CmndRestart, -#ifndef FIRMWARE_MINIMAL_ONLY +#ifndef FIRMWARE_MINIMAL &CmndBacklog, &CmndDelay, &CmndPower, &CmndPowerLock, &CmndTimedPower, &CmndStatus, &CmndState, &CmndSleep, &CmndPowerOnState, &CmndPulsetime, &CmndBlinktime, &CmndBlinkcount, &CmndStateText, &CmndSavedata, &CmndSetoption, &CmndSetoption, &CmndTemperatureResolution, &CmndHumidityResolution, &CmndPressureResolution, &CmndPowerResolution, @@ -93,7 +93,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { #endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 &CmndCpuFrequency #endif // ESP32 -#endif //FIRMWARE_MINIMAL_ONLY +#endif //FIRMWARE_MINIMAL }; const char kWifiConfig[] PROGMEM = @@ -101,7 +101,7 @@ const char kWifiConfig[] PROGMEM = /********************************************************************************************/ -#ifndef FIRMWARE_MINIMAL_ONLY +#ifndef FIRMWARE_MINIMAL void CmndWifiScan(void) { if (XdrvMailbox.data_len > 0) { @@ -249,7 +249,7 @@ void CmndWifiTest(void) #endif //USE_WEBSERVER } -#endif // not defined FIRMWARE_MINIMAL_ONLY +#endif // not defined FIRMWARE_MINIMAL void ResponseCmnd(void) { Response_P(PSTR("{\"%s\":"), XdrvMailbox.command); @@ -829,9 +829,9 @@ void CmndStatus(void) if (payload > MAX_STATUS) { return; } // {"Command":"Error"} if (!Settings->flag.mqtt_enabled && (6 == payload)) { return; } // SetOption3 - Enable MQTT if (!TasmotaGlobal.energy_driver && (9 == payload)) { return; } - #ifndef FIRMWARE_MINIMAL +#ifndef FIRMWARE_MINIMAL if (!CrashFlag() && (12 == payload)) { return; } - #endif // FIRMWARE_MINIMAL +#endif // FIRMWARE_MINIMAL if (!Settings->flag3.shutter_mode && (13 == payload)) { return; } char stemp[200]; @@ -956,9 +956,7 @@ void CmndStatus(void) if ((0 == payload) || (5 == payload)) { #ifdef USE_IPV6 -#ifndef FIRMWARE_MINIMAL if (5 == payload) { WifiDumpAddressesIPv6(); } -#endif // FIRMWARE_MINIMAL Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "1\":\"%s\",\"" D_JSON_DNSSERVER "2\":\"%s\",\"" From 08f99de2a5ebee2afc0a17f085b2195eb90d5982 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:44:26 +0100 Subject: [PATCH 108/205] Save 8k from ESP32 safeboot --- tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino index 0f05631a3..9fe1517a9 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino @@ -45,7 +45,7 @@ WiFiClient EspClient; // Wifi Client - non-TLS #endif // USE_MQTT_AZURE_IOT const char kMqttCommands[] PROGMEM = "|" // No prefix -#ifndef FIRMWARE_MINIMAL_ONLY +#ifndef FIRMWARE_MINIMAL // SetOption synonyms D_SO_MQTTJSONONLY "|" #ifdef USE_MQTT_TLS @@ -67,7 +67,7 @@ const char kMqttCommands[] PROGMEM = "|" // No prefix D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|" D_CMND_MQTTLOG "|" D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN "|" D_CMND_INFORETAIN "|" D_CMND_STATERETAIN "|" D_CMND_STATUSRETAIN -#endif // FIRMWARE_MINIMAL_ONLY +#endif // FIRMWARE_MINIMAL ; SO_SYNONYMS(kMqttSynonyms, @@ -79,7 +79,7 @@ SO_SYNONYMS(kMqttSynonyms, ); void (* const MqttCommand[])(void) PROGMEM = { -#ifndef FIRMWARE_MINIMAL_ONLY +#ifndef FIRMWARE_MINIMAL #if defined(USE_MQTT_TLS) &CmndMqttFingerprint, #endif @@ -94,7 +94,7 @@ void (* const MqttCommand[])(void) PROGMEM = { &CmndFullTopic, &CmndPrefix, &CmndGroupTopic, &CmndTopic, &CmndPublish, &CmndMqttlog, &CmndButtonTopic, &CmndSwitchTopic, &CmndButtonRetain, &CmndSwitchRetain, &CmndPowerRetain, &CmndSensorRetain, &CmndInfoRetain, &CmndStateRetain, &CmndStatusRetain -#endif // FIRMWARE_MINIMAL_ONLY +#endif // FIRMWARE_MINIMAL }; struct MQTT { @@ -2066,6 +2066,7 @@ void MqttSaveSettings(void) { #endif ExecuteWebCommand((char*)cmnd.c_str()); } + #endif // USE_WEBSERVER /*********************************************************************************************\ @@ -2089,7 +2090,7 @@ bool Xdrv02(uint32_t function) case FUNC_WEB_ADD_HANDLER: WebServer_on(PSTR("/" WEB_HANDLE_MQTT), HandleMqttConfiguration); break; -#endif // FIRMWARE_MINIMAL +#endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER case FUNC_COMMAND: result = DecodeCommand(kMqttCommands, MqttCommand, kMqttSynonyms); From a013c7e36d257c4ed8f85c03f6591704788f3693 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:05:03 +0100 Subject: [PATCH 109/205] Fix compile warning --- lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp index b93f2656a..b36a99e0b 100644 --- a/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp +++ b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp @@ -45,7 +45,7 @@ bool MS5837::init(TwoWire &wirePort) { _i2cPort->write(MS5837_PROM_READ+i*2); _i2cPort->endTransmission(); - _i2cPort->requestFrom(MS5837_ADDR,2); + _i2cPort->requestFrom(MS5837_ADDR, (uint8_t)2); C[i] = (_i2cPort->read() << 8) | _i2cPort->read(); } @@ -113,7 +113,7 @@ void MS5837::read() { _i2cPort->write(MS5837_ADC_READ); _i2cPort->endTransmission(); - _i2cPort->requestFrom(MS5837_ADDR,3); + _i2cPort->requestFrom(MS5837_ADDR, (uint8_t)3); D1_pres = 0; D1_pres = _i2cPort->read(); D1_pres = (D1_pres << 8) | _i2cPort->read(); @@ -130,7 +130,7 @@ void MS5837::read() { _i2cPort->write(MS5837_ADC_READ); _i2cPort->endTransmission(); - _i2cPort->requestFrom(MS5837_ADDR,3); + _i2cPort->requestFrom(MS5837_ADDR, (uint8_t)3); D2_temp = 0; D2_temp = _i2cPort->read(); D2_temp = (D2_temp << 8) | _i2cPort->read(); From 6c4e314adcdb263eefead1c036376e195c228762 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:26:07 +0100 Subject: [PATCH 110/205] Gui tuning --- tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index a7c391b81..e3736dbd7 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -989,7 +989,7 @@ void WSContentButton(uint32_t title_index, bool show=true) { } void WSContentSpaceButton(uint32_t title_index, bool show=true) { - WSContentSend_P(PSTR("
"),title_index, show ? "block":"none"); // 5px padding + WSContentSend_P(PSTR("
")); // 5px padding WSContentButton(title_index, show); } @@ -1230,7 +1230,7 @@ void HandleRoot(void) { WSContentSend_P(HTTP_SCRIPT_ROOT_PART2); WSContentSendStyle(); - WSContentSend_P(PSTR("
")); + WSContentSend_P(PSTR("
")); #ifndef FIRMWARE_MINIMAL From 043d80809b5bd633dfe5a6d5bc3a500b646ff0e3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:09:07 +0100 Subject: [PATCH 111/205] Fix shutter slider user control --- .../xdrv_01_9_webserver.ino | 56 +++++++++++++------ .../xdrv_27_esp32_shutter.ino | 6 -- .../tasmota_xdrv_driver/xdrv_27_shutter.ino | 6 -- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index e3736dbd7..4efe0b3f1 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -266,6 +266,13 @@ const char HTTP_HEAD_STYLE3[] PROGMEM = "

%s

" // Module name "

%s

"; // Device name +const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM = + "" + "
%s" + "" + "
" + ""; + const char HTTP_MSG_SLIDER_GRADIENT[] PROGMEM = "" "
" @@ -467,6 +474,11 @@ struct WEB { uint32_t upload_size = 0; uint32_t slider_update_time = 0; int slider[LST_MAX]; +#ifdef ESP8266 + int8_t shutter_slider[MAX_SHUTTERS]; +#else // ESP32 + int8_t shutter_slider[MAX_SHUTTERS_ESP32]; +#endif // ESP8266 uint16_t upload_error = 0; uint8_t state = HTTP_OFF; uint8_t upload_file_type; @@ -605,6 +617,9 @@ void StartWebserver(int type) for (uint32_t i = 0; i < LST_MAX; i++) { Web.slider[i] = -1; } + for (uint32_t i = 0; i < sizeof(Web.shutter_slider); i++) { + Web.shutter_slider[i] = -1; + } if (!Webserver) { Webserver = new ESP8266WebServer((HTTP_MANAGER == type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT); @@ -1168,13 +1183,6 @@ void WebSliderColdWarm(void) { } #endif // USE_LIGHT -const char HTTP_MSG_SLIDER_SHUTTERT[] PROGMEM = - "" - "
%s" - "" - "
" - ""; - void HandleRoot(void) { #ifndef NO_CAPTIVE_PORTAL if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the page. @@ -1332,10 +1340,12 @@ void HandleRoot(void) { shutter_button_idx--; // Right button is previous button (up) bool set_button = ((shutter_button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(shutter_button_idx -1))); snprintf_P(stemp, sizeof(stemp), PSTR("Shutter %d"), shutter_idx +1); - WSContentSend_P(HTTP_MSG_SLIDER_SHUTTERT, + uint32_t shutter_real_to_percent_position = ShutterRealToPercentPosition(-9999, shutter_idx); + Web.shutter_slider[shutter_idx] = (ShutterGetOptions(shutter_idx) & 1) ? (100 - shutter_real_to_percent_position) : shutter_real_to_percent_position; + WSContentSend_P(HTTP_MSG_SLIDER_SHUTTER, (set_button) ? HtmlEscape(GetWebButton(shutter_button_idx -1)).c_str() : stemp, shutter_idx +1, - (ShutterGetOptions(shutter_idx) & 1) ? (100 - ShutterRealToPercentPosition(-9999, shutter_idx)) : ShutterRealToPercentPosition(-9999, shutter_idx), + Web.shutter_slider[shutter_idx], shutter_idx +1); } WSContentSend_P(PSTR("")); @@ -1687,14 +1697,27 @@ bool HandleRootStatusRefresh(void) } } + uint32_t slider_update_time = millis(); #ifdef USE_SHUTTER - if (!msg_exec_javascript) { - WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "web_refresh; // Allow other users to sync screen + } + else if (slider_update_time > Web.slider_update_time) { + Web.slider_update_time = 1; // Allow multiple updates + Web.shutter_slider[i] = current_value; + } + if (!msg_exec_javascript) { + WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM @@ -1741,10 +1763,10 @@ bool HandleRootStatusRefresh(void) } } } +#endif // USE_LIGHT if (1 == Web.slider_update_time) { Web.slider_update_time = 0; } -#endif // USE_LIGHT if (msg_exec_javascript) { WSContentSend_P(PSTR("\">")); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index d166f4460..2be8c6f9d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -45,12 +45,6 @@ #define D_ERROR_FILESYSTEM_NOT_READY "SHT: ERROR File system not enabled" #define D_ERROR_FILE_NOT_FOUND "SHT: ERROR File system not ready or file not found" -const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM = - "" - "
%s%s
" - "
" - "{e}"; - const uint16_t SHUTTER_VERSION = 0x0100; // Latest driver version (See settings deltas below) typedef struct { // depreciated 2023-04-28 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 642d78154..da7c7a138 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -54,12 +54,6 @@ int32_t current_real_position = 0; int32_t current_pwm_velocity = 0; bool sensor_data_reported = false; -const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM = - "" - "
%s%s
" - "
" - "{e}"; - const uint8_t MAX_MODES = 8; enum Shutterposition_mode {SHT_UNDEF, SHT_TIME, SHT_TIME_UP_DOWN, SHT_TIME_GARAGE, SHT_COUNTER, SHT_PWM_VALUE, SHT_PWM_TIME,SHT_AUTOCONFIG}; enum Shutterswitch_mode {SHT_SWITCH, SHT_PULSE,}; From a7669477247701c185865d37e0a1c1fcf4fe6221 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:22:38 +0100 Subject: [PATCH 112/205] Fix compilation --- tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 4efe0b3f1..c2a330269 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -477,7 +477,7 @@ struct WEB { #ifdef ESP8266 int8_t shutter_slider[MAX_SHUTTERS]; #else // ESP32 - int8_t shutter_slider[MAX_SHUTTERS_ESP32]; + int8_t shutter_slider[16]; // MAX_SHUTTERS_ESP32 #endif // ESP8266 uint16_t upload_error = 0; uint8_t state = HTTP_OFF; From caa63f437c4e70913e95a44538abc62defc21ed1 Mon Sep 17 00:00:00 2001 From: vtHydroponics <132159689+vtHydroponics@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:24:18 -0500 Subject: [PATCH 113/205] MS5837 console calibration options and code cleanup (#22466) * Finalized gain/integration adjustment trees * Fixed the bugs * works but polishing code * need to debug pressure in bmp * updated temp to change via setoption8 command from tasmota * sensor table working, value reporting working, need to update dependency on sensor duality * working * updated file name for ms5837 xsns file * final working with renamed for current updates (128->116) * resolved PR comments for extra spaces, xi2c_96 * removed extra spaces, added unit for inches across languages * removed inches as a unit from language files * removed extra code, commented debug lines * rebased with dev branch, fixed sensor116 command --- .../BlueRobotics_MS5837_Library/MS5837.cpp | 2 +- tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp index b36a99e0b..a8e33284e 100644 --- a/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp +++ b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp @@ -255,4 +255,4 @@ uint8_t MS5837::crc4(uint16_t n_prom[]) { n_rem = ((n_rem >> 12) & 0x000F); return n_rem ^ 0x00; -} +} \ No newline at end of file diff --git a/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino b/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino index 49bc8db10..403b1c3f9 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino @@ -108,12 +108,27 @@ void MS5837Show(bool json) { bool ms5837CommandSensor() { bool serviced = true; + char argument[XdrvMailbox.data_len]; + long value = 0; + + for (uint32_t ca = 0; ca < XdrvMailbox.data_len; ca++) { + if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; } + } + + bool any_value = (strchr(XdrvMailbox.data, ',') != nullptr); + if (any_value) { value = strtol(ArgV(argument, 2), nullptr, 10); } + switch (XdrvMailbox.payload) { case 0: MS5837Show(0); #ifdef USE_BMP ms5837_pressure_offset = bmp_sensors[0].bmp_pressure - ms5837_sensor.pressure(); #endif // USE_BMP + Response_P(PSTR("Set MS5837 pressure offset to %f"),ms5837_pressure_offset); + break; + case 1: + ms5837_pressure_offset = value; + Response_P(PSTR("Set MS5837 pressure offset to %f"),ms5837_pressure_offset); break; } return serviced; From bdc7e0a65b0795747ebfde84731858fd6b6e0072 Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:27:37 +0100 Subject: [PATCH 114/205] [Solax X1] Increase receive buffer (#22467) Increase receive buffer, because it was too small, when using Software Serial. --- tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino index 5e69d278d..d0f8ad9e9 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino @@ -329,7 +329,7 @@ void solaxX1_SwitchMeterMode(bool MeterMode) { /*********************************************************************************************/ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds - uint8_t DataRead[80] = {0}; + uint8_t DataRead[256] = {0}; uint8_t TempData[16] = {0}; char TempDataChar[32]; float TempFloat; @@ -571,7 +571,7 @@ return; void solaxX1_SnsInit(void) { AddLog(LOG_LEVEL_INFO, PSTR("SX1: Init - RX-pin: %d, TX-pin: %d, RTS-pin: %d"), Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), Pin(GPIO_SOLAXX1_RTS)); - solaxX1Serial = new TasmotaSerial(Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), 1); + solaxX1Serial = new TasmotaSerial(Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), 1, 0, 256); if (solaxX1Serial->begin(SOLAXX1_SPEED)) { if (solaxX1Serial->hardwareSerial()) { ClaimSerial(); } #ifdef ESP32 From 331fd1426851adffd244a3a0f412dc086667a809 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:32:50 +0100 Subject: [PATCH 115/205] Add Settings->ms5837_pressure_offset (#22466) --- tasmota/include/tasmota_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index ceeb9cc8d..facaa1471 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -846,9 +846,10 @@ typedef struct { uint8_t modbus_sconfig; // F62 uint8_t windmeter_measure_intvl; // F63 - uint8_t free_f64[12]; // F64 - Decrement if adding new Setting variables just above and below + uint8_t free_f64[8]; // F64 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below + float ms5837_pressure_offset; // F6C uint32_t touch_threshold; // F70 SOBitfield6 flag6; // F74 uint16_t flowratemeter_calibration[2];// F78 From b903c6a8434f1156547a6b3beba626c038a4117e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 11 Nov 2024 18:18:19 +0100 Subject: [PATCH 116/205] enable Ethernet in all safeboot firmware (except c2) (#21983) * enable Ethernet in all safeboot firmware (except c2) * undef SPI for C2 in variant minimal --- tasmota/include/tasmota_configurations_ESP32.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 82524e9f5..2bcbd27f2 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -190,14 +190,12 @@ #undef USE_ESP32_WDT // disable watchdog on SAFEBOOT until more testing is done -#if CONFIG_IDF_TARGET_ESP32 -#if CONFIG_FREERTOS_UNICORE - #undef USE_MQTT_TLS +#if CONFIG_FREERTOS_UNICORE || CONFIG_IDF_TARGET_ESP32S3 +// #undef USE_MQTT_TLS // #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge console Tee (+4.5k code) #define USE_SPI // Make SPI Ethernet adapters useable (+124 bytes) #define USE_ETHERNET -#endif // CONFIG_FREERTOS_UNICORE -#endif // CONFIG_IDF_TARGET_ESP32 +#endif // CONFIG_FREERTOS_UNICORE || CONFIG_IDF_TARGET_ESP32S3 #endif // FIRMWARE_SAFEBOOT @@ -839,6 +837,9 @@ #ifdef CONFIG_IDF_TARGET_ESP32C2 #undef USE_ETHERNET + #ifdef FIRMWARE_MINIMAL + #undef USE_SPI + #endif // FIRMWARE_MINIMAL #endif // CONFIG_IDF_TARGET_ESP32C2 #endif // ESP32 From cf94ccf59ca3bf6cc861519446e81bc4bbb1836f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 11 Nov 2024 22:44:18 +0100 Subject: [PATCH 117/205] Bump version v14.3.0.6 - Add command ``WebColor20`` to control color of Button when Off --- CHANGELOG.md | 14 +++++++++++--- RELEASENOTES.md | 3 ++- tasmota/include/tasmota_configurations.h | 2 -- tasmota/include/tasmota_configurations_ESP32.h | 2 -- tasmota/include/tasmota_globals.h | 7 +++++-- tasmota/include/tasmota_version.h | 2 +- tasmota/my_user_config.h | 6 ++++-- tasmota/tasmota_support/settings.ino | 4 ++++ .../tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 8 ++++---- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 4 ++-- 10 files changed, 33 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a95390c19..d8644d97b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,17 +3,25 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.3.0.5] +## [14.3.0.6] ### Added -- ESP32 MI32 legacy add config operations (#22458) +- Add command ``WebColor20`` to control color of Button when Off ### Breaking Changed ### Changed -- Redesign GUI adding feedback to buttons, shutters and lights ### Fixed +### Removed + +## [14.3.0.5] 20241111 +### Added +- ESP32 MI32 legacy add config operations (#22458) + +### Changed +- Redesign GUI adding feedback to buttons, shutters and lights + ### Removed - Command ``SetOption161 1`` to disable web page slider updates by commands diff --git a/RELEASENOTES.md b/RELEASENOTES.md index efa1111c5..32d0255da 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -114,8 +114,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.3.0.5 +## Changelog v14.3.0.6 ### Added +- Add command ``WebColor20`` to control color of Button when Off - DALI support for short addresses (gear) and groups - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h index 36721339b..1260892a0 100644 --- a/tasmota/include/tasmota_configurations.h +++ b/tasmota/include/tasmota_configurations.h @@ -851,8 +851,6 @@ #define CODE_IMAGE_STR "minimal" #endif -#define FIRMWARE_MINIMAL_ONLY - #undef FIRMWARE_LITE // Disable tasmota-lite with no sensors #undef FIRMWARE_SENSORS // Disable tasmota-sensors with useful sensors enabled #undef FIRMWARE_KNX_NO_EMULATION // Disable tasmota-knx with KNX but without Emulation diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 2bcbd27f2..9eb52a7b5 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -173,8 +173,6 @@ #define FIRMWARE_MINIMAL -#undef FIRMWARE_MINIMAL_ONLY - #undef USE_ESP32_SENSORS #undef USE_UFILESYS #undef GUI_TRASH_FILE diff --git a/tasmota/include/tasmota_globals.h b/tasmota/include/tasmota_globals.h index db8d24f0c..7e6ba23b3 100644 --- a/tasmota/include/tasmota_globals.h +++ b/tasmota/include/tasmota_globals.h @@ -503,13 +503,16 @@ const char WIFI_HOSTNAME[] = WIFI_DEFAULT_HOSTNAME; // Override by user_confi #ifndef COLOR_TITLE_TEXT #define COLOR_TITLE_TEXT COLOR_TEXT // Title text color defaults to global text color either dark or light #endif +#ifndef COLOR_BUTTON_OFF +#define COLOR_BUTTON_OFF "#08405e" // Button color when off - Darkest blueish +#endif enum WebColors { COL_TEXT, COL_BACKGROUND, COL_FORM, COL_INPUT_TEXT, COL_INPUT, COL_CONSOLE_TEXT, COL_CONSOLE, COL_TEXT_WARNING, COL_TEXT_SUCCESS, COL_BUTTON_TEXT, COL_BUTTON, COL_BUTTON_HOVER, COL_BUTTON_RESET, COL_BUTTON_RESET_HOVER, COL_BUTTON_SAVE, COL_BUTTON_SAVE_HOVER, - COL_TIMER_TAB_TEXT, COL_TIMER_TAB_BACKGROUND, COL_TITLE, + COL_TIMER_TAB_TEXT, COL_TIMER_TAB_BACKGROUND, COL_TITLE, COL_BUTTON_OFF, COL_LAST }; const char kWebColors[] PROGMEM = @@ -517,7 +520,7 @@ const char kWebColors[] PROGMEM = COLOR_INPUT_TEXT "|" COLOR_INPUT "|" COLOR_CONSOLE_TEXT "|" COLOR_CONSOLE "|" COLOR_TEXT_WARNING "|" COLOR_TEXT_SUCCESS "|" COLOR_BUTTON_TEXT "|" COLOR_BUTTON "|" COLOR_BUTTON_HOVER "|" COLOR_BUTTON_RESET "|" COLOR_BUTTON_RESET_HOVER "|" COLOR_BUTTON_SAVE "|" COLOR_BUTTON_SAVE_HOVER "|" - COLOR_TIMER_TAB_TEXT "|" COLOR_TIMER_TAB_BACKGROUND "|" COLOR_TITLE_TEXT; + COLOR_TIMER_TAB_TEXT "|" COLOR_TIMER_TAB_BACKGROUND "|" COLOR_TITLE_TEXT "|" COLOR_BUTTON_OFF; /*********************************************************************************************\ * Macros diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 78cccdb21..c7f0d2d3f 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E030005; // 14.3.0.5 +const uint32_t TASMOTA_VERSION = 0x0E030006; // 14.3.0.6 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index c28e33ca3..d6822db2f 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -190,7 +190,7 @@ // -- HTTP GUI Colors ----------------------------- // HTML hex color codes. Only 3 and 6 digit hex string values are supported!! See https://www.w3schools.com/colors/colors_hex.asp // Light theme - pre v7 -// WebColor {"WebColor":["#000","#fff","#f2f2f2","#000","#fff","#000","#fff","#f00","#008000","#fff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#fff","#999","#000"]} +// WebColor {"WebColor":["#000","#fff","#f2f2f2","#000","#fff","#000","#fff","#f00","#008000","#fff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#fff","#999","#000","#08405e"]} /* #define COLOR_TEXT "#000" // [WebColor1] Global text color - Black #define COLOR_BACKGROUND "#fff" // [WebColor2] Global background color - White @@ -211,9 +211,10 @@ #define COLOR_TIMER_TAB_TEXT "#fff" // [WebColor17] Config timer tab text color - White #define COLOR_TIMER_TAB_BACKGROUND "#999" // [WebColor18] Config timer tab background color - Dark gray #define COLOR_TITLE_TEXT "#000" // [WebColor19] Title text color - Whiteish +#define COLOR_BUTTON_OFF "#08405e" // [WebColor20] Button color when off - Darkest blueish */ // Dark theme -// WebColor {"WebColor":["#eaeaea","#252525","#4f4f4f","#000","#ddd","#65c115","#1f1f1f","#ff5661","#008000","#faffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#faffff","#999","#eaeaea"]} +// WebColor {"WebColor":["#eaeaea","#252525","#4f4f4f","#000","#ddd","#65c115","#1f1f1f","#ff5661","#008000","#faffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#faffff","#999","#eaeaea","#08405e"]} #define COLOR_TEXT "#eaeaea" // [WebColor1] Global text color - Very light gray #define COLOR_BACKGROUND "#252525" // [WebColor2] Global background color - Very dark gray (mostly black) #define COLOR_FORM "#4f4f4f" // [WebColor3] Form background color - Very dark gray @@ -233,6 +234,7 @@ #define COLOR_TIMER_TAB_TEXT "#faffff" // [WebColor17] Config timer tab text color - Very pale (mostly white) cyan. #define COLOR_TIMER_TAB_BACKGROUND "#999" // [WebColor18] Config timer tab background color - Dark gray #define COLOR_TITLE_TEXT "#eaeaea" // [WebColor19] Title text color - Very light gray +#define COLOR_BUTTON_OFF "#08405e" // [WebColor20] Button color when off - Darkest blueish // -- KNX ----------------------------------------- #define KNX_ENABLED false // [Knx_Enabled] Enable KNX protocol diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index 09376bb05..db5aa35c2 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -1843,6 +1843,10 @@ void SettingsDelta(void) { if (Settings->version < 0x0E030004) { // 14.3.0.4 Settings->mbflag2.dali_group_sliders = 2; } + if (Settings->version < 0x0E030006) { // 14.3.0.6 + char scolor[10]; + WebHexCode(COL_BUTTON_OFF, GetTextIndexed(scolor, sizeof(scolor), COL_BUTTON_OFF, kWebColors)); + } Settings->version = TASMOTA_VERSION; SettingsSave(1); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index c2a330269..83d70475c 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1519,7 +1519,7 @@ void HandleRoot(void) { #endif // USE_SONOFF_IFAN if (not_active) { - WSContentSend_P(PSTR("eb('o%d').style.background='#%06x';"), idx, WebColor(COL_FORM)); + WSContentSend_P(PSTR("eb('o%d').style.background='#%06x';"), idx, WebColor(COL_BUTTON_OFF)); } } WSContentSend_P(PSTR("")); @@ -1693,7 +1693,7 @@ bool HandleRootStatusRefresh(void) #endif // USE_SONOFF_IFAN WSContentSend_P(PSTR("eb('o%d').style.background='#%06x';"), - idx, WebColor((active) ? COL_BUTTON : COL_FORM)); + idx, WebColor((active) ? COL_BUTTON : COL_BUTTON_OFF)); } } @@ -3854,9 +3854,9 @@ int WebGetConfig(char *buffer) { bool JsonWebColor(const char* dataBuf) { // Default (Dark theme) - // {"WebColor":["#eaeaea","#252525","#4f4f4f","#000","#ddd","#65c115","#1f1f1f","#ff5661","#008000","#faffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#faffff","#999","#eaeaea"]} + // {"WebColor":["#eaeaea","#252525","#4f4f4f","#000","#ddd","#65c115","#1f1f1f","#ff5661","#008000","#faffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#faffff","#999","#eaeaea","#08405e"]} // Default pre v7 (Light theme) - // {"WebColor":["#000","#fff","#f2f2f2","#000","#fff","#000","#fff","#f00","#008000","#fff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#fff","#999","#000"]} // {"WebColor":["#000000","#ffffff","#f2f2f2","#000000","#ffffff","#000000","#ffffff","#ff0000","#008000","#ffffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#ffffff","#999999","#000000"]} + // {"WebColor":["#000","#fff","#f2f2f2","#000","#fff","#000","#fff","#f00","#008000","#fff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#fff","#999","#000","#08405e"]} // {"WebColor":["#000000","#ffffff","#f2f2f2","#000000","#ffffff","#000000","#ffffff","#ff0000","#008000","#ffffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#ffffff","#999999","#000000","#08405e"]} JsonParser parser((char*) dataBuf); JsonParserObject root = parser.getRootObject(); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index d56f22e4e..252b6048e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -1247,7 +1247,7 @@ void DaliWebAddMainSlider(void) { Dali->web_dimmer[i] = Dali->dimmer[i]; WSContentSend_P(HTTP_MSG_SLIDER_DALI, // Brightness - Black to White i, // k75 - WebColor((Dali->power[i]) ? COL_BUTTON : COL_FORM), + WebColor((Dali->power[i]) ? COL_BUTTON : COL_BUTTON_OFF), i, // k75= (0==i)?"B":"G", // B (Broadcast) or G1 to G16 (Group) (0==i)?"":itoa(i, number, 10), @@ -1296,7 +1296,7 @@ void DaliShow(bool json) { uint32_t slider_update_time = millis(); for (uint32_t i = Settings->sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { // DaliLight 0/1, DaliGroupSliders WSContentSend_P(PSTR("eb('k75%d').style='background:#%06x';"), - i, WebColor((Dali->power[i]) ? COL_BUTTON : COL_FORM)); + i, WebColor((Dali->power[i]) ? COL_BUTTON : COL_BUTTON_OFF)); if (Dali->dimmer[i] != Dali->web_dimmer[i]) { if (0 == Dali->slider_update_time) { Dali->slider_update_time = slider_update_time + Settings->web_refresh; // Allow other users to sync screen From 7dd1e2a028cea4adb91b1d9d314993332bc48856 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:32:10 +0100 Subject: [PATCH 118/205] Minor changes webserver and dali --- .../xdrv_01_9_webserver.ino | 736 +++++++++++------- tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 84 +- 2 files changed, 504 insertions(+), 316 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 83d70475c..a2bbed1ac 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -488,15 +488,18 @@ struct WEB { bool initial_config = false; } Web; +/*********************************************************************************************/ + // Helper function to avoid code duplication (saves 4k Flash) // arg can be in PROGMEM -static void WebGetArg(const char* arg, char* out, size_t max) -{ +static void WebGetArg(const char* arg, char* out, size_t max) { String s = Webserver->arg((const __FlashStringHelper *)arg); strlcpy(out, s.c_str(), max); // out[max-1] = '\0'; // Ensure terminating NUL } +/*-------------------------------------------------------------------------------------------*/ + String AddWebCommand(const char* command, const char* arg, const char* dflt) { /* // OK but fixed max argument @@ -542,27 +545,31 @@ String AddWebCommand(const char* command, const char* arg, const char* dflt) { return result; } -static bool WifiIsInManagerMode(){ +/*-------------------------------------------------------------------------------------------*/ + +static bool WifiIsInManagerMode(void) { return (HTTP_MANAGER == Web.state || HTTP_MANAGER_RESET_ONLY == Web.state); } -void ShowWebSource(uint32_t source) -{ +/*-------------------------------------------------------------------------------------------*/ + +void ShowWebSource(uint32_t source) { if ((source > 0) && (source < SRC_MAX)) { char stemp1[20]; AddLog(LOG_LEVEL_DEBUG, PSTR("SRC: %s from %s"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource), Webserver->client().remoteIP().toString().c_str()); } } +/*-------------------------------------------------------------------------------------------*/ + +void ExecuteWebCommand(char* svalue, uint32_t source = SRC_WEBGUI); void ExecuteWebCommand(char* svalue, uint32_t source) { ShowWebSource(source); TasmotaGlobal.last_source = source; ExecuteCommand(svalue, SRC_IGNORE); } -void ExecuteWebCommand(char* svalue) { - ExecuteWebCommand(svalue, SRC_WEBGUI); -} +/*-------------------------------------------------------------------------------------------*/ // replace the series of `Webserver->on()` with a table in PROGMEM typedef struct WebServerDispatch_t { @@ -598,6 +605,8 @@ const WebServerDispatch_t WebServerDispatch[] PROGMEM = { #endif // Not FIRMWARE_MINIMAL }; +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + void WebServer_on(const char * prefix, void (*func)(void), uint8_t method = HTTP_ANY) { if (Webserver == nullptr) { return; } #ifdef ESP8266 @@ -608,9 +617,10 @@ void WebServer_on(const char * prefix, void (*func)(void), uint8_t method = HTTP #endif // ESP32 } +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + // Always listens to all interfaces, so we don't need an IP address anymore -void StartWebserver(int type) -{ +void StartWebserver(int type) { if (!Settings->web_refresh) { Settings->web_refresh = HTTP_REFRESH_TIME; } if (!Web.state) { @@ -664,8 +674,9 @@ void StartWebserver(int type) } } -void StopWebserver(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void StopWebserver(void) { if (Web.state) { Webserver->close(); Web.state = HTTP_OFF; @@ -673,8 +684,9 @@ void StopWebserver(void) } } -void WifiManagerBegin(bool reset_only) -{ +/*-------------------------------------------------------------------------------------------*/ + +void WifiManagerBegin(bool reset_only) { // setup AP if (!Web.initial_config) { AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES)); } if (!TasmotaGlobal.global_state.wifi_down) { @@ -702,16 +714,16 @@ void WifiManagerBegin(bool reset_only) StartWebserver((reset_only ? HTTP_MANAGER_RESET_ONLY : HTTP_MANAGER)); } -void PollDnsWebserver(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void PollDnsWebserver(void) { if (DnsServer) { DnsServer->processNextRequest(); } if (Webserver) { Webserver->handleClient(); } } /*********************************************************************************************/ -bool WebAuthenticate(void) -{ +bool WebAuthenticate(void) { if (strlen(SettingsText(SET_WEBPWD)) && (HTTP_MANAGER_RESET_ONLY != Web.state)) { return Webserver->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD)); } else { @@ -719,8 +731,9 @@ bool WebAuthenticate(void) } } -bool HttpCheckPriviledgedAccess(bool autorequestauth = true) -{ +/*-------------------------------------------------------------------------------------------*/ + +bool HttpCheckPriviledgedAccess(bool autorequestauth = true) { if (HTTP_USER == Web.state) { HandleRoot(); return false; @@ -761,16 +774,18 @@ bool HttpCheckPriviledgedAccess(bool autorequestauth = true) } #ifdef USE_CORS -void HttpHeaderCors(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void HttpHeaderCors(void) { if (strlen(SettingsText(SET_CORS))) { Webserver->sendHeader(F("Access-Control-Allow-Origin"), SettingsText(SET_CORS)); } } #endif -void WSHeaderSend(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void WSHeaderSend(void) { char server[32]; snprintf_P(server, sizeof(server), PSTR("Tasmota/%s (%s)"), TasmotaGlobal.version, GetDeviceHardware().c_str()); Webserver->sendHeader(F("Server"), server); @@ -782,9 +797,9 @@ void WSHeaderSend(void) #endif } -/********************************************************************************************** -* HTTP Content Page handler -**********************************************************************************************/ +/*********************************************************************************************\ + * HTTP Content Page handler +\*********************************************************************************************/ void WSSend(int code, int ctype, const String& content) { @@ -792,9 +807,9 @@ void WSSend(int code, int ctype, const String& content) Webserver->send(code, GetTextIndexed(ct, sizeof(ct), ctype, kContentTypes), content); } -/********************************************************************************************** -* HTTP Content Chunk handler -**********************************************************************************************/ +/*********************************************************************************************\ + * HTTP Content Chunk handler +\*********************************************************************************************/ void WSContentBegin(int code, int ctype) { Webserver->client().flush(); @@ -804,6 +819,8 @@ void WSContentBegin(int code, int ctype) { Web.chunk_buffer = ""; } +/*-------------------------------------------------------------------------------------------*/ + void _WSContentSend(const char* content, size_t size) { // Lowest level sendContent for all core versions Webserver->sendContent(content, size); @@ -811,10 +828,14 @@ void _WSContentSend(const char* content, size_t size) { // Lowest level sendCon DEBUG_CORE_LOG(PSTR("WEB: Chunk size %d"), size); } +/*-------------------------------------------------------------------------------------------*/ + void _WSContentSend(const String& content) { // Low level sendContent for all core versions _WSContentSend(content.c_str(), content.length()); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentFlush(void) { if (Web.chunk_buffer.length() > 0) { _WSContentSend(Web.chunk_buffer); // Flush chunk buffer @@ -822,6 +843,8 @@ void WSContentFlush(void) { } } +/*-------------------------------------------------------------------------------------------*/ + void _WSContentSendBufferChunk(const char* content) { int len = strlen(content); if (len < CHUNKED_BUFFER_SIZE) { // Append chunk buffer with small content @@ -836,6 +859,8 @@ void _WSContentSendBufferChunk(const char* content) { } } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSend(const char* content, size_t size) { // To speed up transmission use chunked buffer if possible if (size < CHUNKED_BUFFER_SIZE) { @@ -849,6 +874,8 @@ void WSContentSend(const char* content, size_t size) { } } +/*-------------------------------------------------------------------------------------------*/ + void _WSContentSendBuffer(bool decimal, const char * formatP, va_list arg) { char* content = ext_vsnprintf_malloc_P(formatP, arg); if (content == nullptr) { return; } // Avoid crash @@ -870,6 +897,8 @@ void _WSContentSendBuffer(bool decimal, const char * formatP, va_list arg) { free(content); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSend_P(const char* formatP, ...) { // Content send snprintf_P char data // This uses char strings. Be aware of sending %% if % is needed va_list arg; @@ -878,6 +907,8 @@ void WSContentSend_P(const char* formatP, ...) { // Content send snprintf_P ch va_end(arg); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSend_PD(const char* formatP, ...) { // Content send snprintf_P char data checked for decimal separator // This uses char strings. Be aware of sending %% if % is needed va_list arg; @@ -886,6 +917,8 @@ void WSContentSend_PD(const char* formatP, ...) { // Content send snprintf_P ch va_end(arg); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentStart_P(const char* title, bool auth) { if (auth && !WebAuthenticate()) { return Webserver->requestAuthentication(); @@ -898,10 +931,14 @@ void WSContentStart_P(const char* title, bool auth) { } } +/*-------------------------------------------------------------------------------------------*/ + void WSContentStart_P(const char* title) { WSContentStart_P(title, true); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSendStyle_P(const char* formatP, ...) { if ( WifiIsInManagerMode() && (!Web.initial_config) ) { if (WifiConfigCounter()) { @@ -975,14 +1012,20 @@ void WSContentSendStyle_P(const char* formatP, ...) { WSContentSend_P(PSTR("
")); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSendStyle(void) { WSContentSendStyle_P(nullptr); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentTextCenterStart(uint32_t color) { WSContentSend_P(PSTR("
"), color); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentButton(uint32_t title_index, bool show=true) { char action[4]; char title[100]; // Large to accomodate UTF-16 as used by Russian @@ -1003,11 +1046,15 @@ void WSContentButton(uint32_t title_index, bool show=true) { } } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSpaceButton(uint32_t title_index, bool show=true) { WSContentSend_P(PSTR("
")); // 5px padding WSContentButton(title_index, show); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSeparator(uint32_t state) { // Send two column separator static bool request = false; @@ -1029,18 +1076,26 @@ void WSContentSeparator(uint32_t state) { } } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSend_Temp(const char *types, float f_temperature) { WSContentSend_PD(HTTP_SNS_F_TEMP, types, Settings->flag2.temperature_resolution, &f_temperature, TempUnit()); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSend_Voltage(const char *types, float f_voltage) { WSContentSend_PD(HTTP_SNS_F_VOLTAGE, types, Settings->flag2.voltage_resolution, &f_voltage); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSend_CurrentMA(const char *types, float f_current) { WSContentSend_PD(HTTP_SNS_F_CURRENT_MA, types, Settings->flag2.current_resolution, &f_current); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSend_THD(const char *types, float f_temperature, float f_humidity) { WSContentSend_Temp(types, f_temperature); @@ -1055,6 +1110,8 @@ void WSContentSend_THD(const char *types, float f_temperature, float f_humidity) #endif // USE_HEAT_INDEX } +/*-------------------------------------------------------------------------------------------*/ + void WSContentEnd(void) { WSContentFlush(); // Flush chunk buffer _WSContentSend(""); // Signal end of chunked content @@ -1064,6 +1121,8 @@ void WSContentEnd(void) { #endif // defined(USE_MI_ESP32) && !defined(USE_BLE_ESP32) } +/*-------------------------------------------------------------------------------------------*/ + void WSContentStop(void) { if ( WifiIsInManagerMode() && (!Web.initial_config) ) { if (WifiConfigCounter()) { @@ -1139,8 +1198,23 @@ void WebRestart(uint32_t type) { /*********************************************************************************************/ -void HandleWifiLogin(void) -{ +uint32_t WebUseManagementSubmenu(void) { + static uint32_t management_count = 0; + + if (!management_count) { + XdrvMailbox.index = 1; + XdrvXsnsCall(FUNC_WEB_ADD_CONSOLE_BUTTON); + XdrvCall(FUNC_WEB_ADD_MANAGEMENT_BUTTON); + management_count = XdrvMailbox.index; + } + return management_count -1; +} + +/*********************************************************************************************\ + * HandleRoot +\*********************************************************************************************/ + +void HandleWifiLogin(void) { WSContentStart_P(PSTR(D_CONFIGURE_WIFI), false); // false means show page no matter if the client has or has not credentials WSContentSendStyle(); WSContentSend_P(HTTP_FORM_LOGIN); @@ -1155,19 +1229,9 @@ void HandleWifiLogin(void) WSContentStop(); } -uint32_t WebUseManagementSubmenu(void) { - static uint32_t management_count = 0; - - if (!management_count) { - XdrvMailbox.index = 1; - XdrvXsnsCall(FUNC_WEB_ADD_CONSOLE_BUTTON); - XdrvCall(FUNC_WEB_ADD_MANAGEMENT_BUTTON); - management_count = XdrvMailbox.index; - } - return management_count -1; -} - #ifdef USE_LIGHT +/*-------------------------------------------------------------------------------------------*/ + void WebSliderColdWarm(void) { Web.slider[0] = LightGetColorTemp(); WSContentSend_P(PSTR("")); @@ -1183,6 +1247,8 @@ void WebSliderColdWarm(void) { } #endif // USE_LIGHT +/*-------------------------------------------------------------------------------------------*/ + void HandleRoot(void) { #ifndef NO_CAPTIVE_PORTAL if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the page. @@ -1546,8 +1612,43 @@ void HandleRoot(void) { WSContentStop(); } -bool HandleRootStatusRefresh(void) -{ +/*-------------------------------------------------------------------------------------------*\ + * HandleRootStatusRefresh +\*-------------------------------------------------------------------------------------------*/ + +#ifdef USE_SHUTTER +int32_t IsShutterWebButton(uint32_t idx) { + /* 0: Not a shutter, 1..4: shutter up idx, -1..-4: shutter down idx */ + int32_t ShutterWebButton = 0; + if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support + for (uint32_t i = 0; i < TasmotaGlobal.shutters_present ; i++) { + if (ShutterGetStartRelay(i) && ((ShutterGetStartRelay(i) == idx) || (ShutterGetStartRelay(i) == (idx-1)))) { + ShutterWebButton = (ShutterGetStartRelay(i) == idx) ? (i+1): (-1-i); + break; + } + } + } + return ShutterWebButton; +} +#endif // USE_SHUTTER + +/*-------------------------------------------------------------------------------------------*/ + +bool WebUpdateSliderTime(void) { + uint32_t slider_update_time = millis(); + if (0 == Web.slider_update_time) { + Web.slider_update_time = slider_update_time + Settings->web_refresh; // Allow other users to sync screen + } + else if (slider_update_time > Web.slider_update_time) { + Web.slider_update_time = 1; // Allow multiple updates + return true; + } + return false; +} + +/*-------------------------------------------------------------------------------------------*/ + +bool HandleRootStatusRefresh(void) { if (!WebAuthenticate()) { Webserver->requestAuthentication(); return true; @@ -1697,18 +1798,13 @@ bool HandleRootStatusRefresh(void) } } - uint32_t slider_update_time = millis(); #ifdef USE_SHUTTER for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) { if (Web.shutter_slider[i] != -1) { uint32_t shutter_real_to_percent_position = ShutterRealToPercentPosition(-9999, i); uint32_t current_value = (ShutterGetOptions(i) & 1) ? (100 - shutter_real_to_percent_position) : shutter_real_to_percent_position; if (current_value != Web.shutter_slider[i]) { - if (0 == Web.slider_update_time) { - Web.slider_update_time = slider_update_time + Settings->web_refresh; // Allow other users to sync screen - } - else if (slider_update_time > Web.slider_update_time) { - Web.slider_update_time = 1; // Allow multiple updates + if (WebUpdateSliderTime()) { Web.shutter_slider[i] = current_value; } if (!msg_exec_javascript) { @@ -1748,11 +1844,7 @@ bool HandleRootStatusRefresh(void) current_value = changeUIntScale(Settings->light_color[i], 0, 255, 0, 100); } if (current_value != Web.slider[i]) { - if (0 == Web.slider_update_time) { - Web.slider_update_time = slider_update_time + Settings->web_refresh; // Allow other users to sync screen - } - else if (slider_update_time > Web.slider_update_time) { - Web.slider_update_time = 1; // Allow multiple updates + if (WebUpdateSliderTime()) { Web.slider[i] = current_value; } if (!msg_exec_javascript) { @@ -1764,9 +1856,6 @@ bool HandleRootStatusRefresh(void) } } #endif // USE_LIGHT - if (1 == Web.slider_update_time) { - Web.slider_update_time = 0; - } if (msg_exec_javascript) { WSContentSend_P(PSTR("\">")); @@ -1781,6 +1870,10 @@ bool HandleRootStatusRefresh(void) XsnsXdrvCall(FUNC_WEB_SENSOR); WSContentSend_P(PSTR("")); + if (1 == Web.slider_update_time) { + Web.slider_update_time = 0; + } + WSContentSend_P(PSTR("\n\n")); // Prep for SSE WSContentEnd(); @@ -1789,28 +1882,13 @@ bool HandleRootStatusRefresh(void) return true; } -#ifdef USE_SHUTTER -int32_t IsShutterWebButton(uint32_t idx) { - /* 0: Not a shutter, 1..4: shutter up idx, -1..-4: shutter down idx */ - int32_t ShutterWebButton = 0; - if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support - for (uint32_t i = 0; i < TasmotaGlobal.shutters_present ; i++) { - if (ShutterGetStartRelay(i) && ((ShutterGetStartRelay(i) == idx) || (ShutterGetStartRelay(i) == (idx-1)))) { - ShutterWebButton = (ShutterGetStartRelay(i) == idx) ? (i+1): (-1-i); - break; - } - } - } - return ShutterWebButton; -} -#endif // USE_SHUTTER - -/*-------------------------------------------------------------------------------------------*/ - #ifndef FIRMWARE_MINIMAL -void HandleConfiguration(void) -{ +/*********************************************************************************************\ + * HandleConfiguration +\*********************************************************************************************/ + +void HandleConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURATION)); @@ -1835,7 +1913,9 @@ void HandleConfiguration(void) WSContentStop(); } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleTemplateConfiguration +\*********************************************************************************************/ void WSContentSendNiceLists(uint32_t option) { char stemp[30]; // Template number and Sensor name @@ -1875,6 +1955,8 @@ void WSContentSendNiceLists(uint32_t option) { WSContentSend_P(PSTR("];")); } +/*-------------------------------------------------------------------------------------------*/ + #ifdef ESP8266 #ifdef USE_ADC void WSContentSendAdcNiceList(uint32_t option) { @@ -1993,6 +2075,8 @@ void HandleTemplateConfiguration(void) { WSContentStop(); } +/*-------------------------------------------------------------------------------------------*/ + uint16_t WebGetGpioArg(uint32_t i) { char webindex[5]; // WebGetArg name snprintf_P(webindex, sizeof(webindex), PSTR("g%d"), i); @@ -2008,6 +2092,8 @@ uint16_t WebGetGpioArg(uint32_t i) { return gpio; } +/*-------------------------------------------------------------------------------------------*/ + void TemplateSaveSettings(void) { char tmp[TOPSZ]; // WebGetArg NAME and GPIO/BASE/FLAG byte value char command[300]; // Template command string @@ -2066,7 +2152,9 @@ void TemplateSaveSettings(void) { ExecuteWebCommand(command); } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleModuleConfiguration +\*********************************************************************************************/ void HandleModuleConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -2134,6 +2222,8 @@ void HandleModuleConfiguration(void) { WSContentStop(); } +/*-------------------------------------------------------------------------------------------*/ + void ModuleSaveSettings(void) { char tmp[8]; // WebGetArg numbers only WebGetArg(PSTR("g99"), tmp, sizeof(tmp)); // Module @@ -2157,7 +2247,9 @@ void ModuleSaveSettings(void) { ExecuteWebCommand(command); } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleWifiConfiguration +\*********************************************************************************************/ void HandleWifiConfiguration(void) { char tmp[TOPSZ]; // Max length is currently 150 @@ -2408,6 +2500,8 @@ void HandleWifiConfiguration(void) { WSContentStop(); } +/*-------------------------------------------------------------------------------------------*/ + void WifiSaveSettings(void) { String cmnd = F(D_CMND_BACKLOG "0 "); cmnd += AddWebCommand(PSTR(D_CMND_HOSTNAME), PSTR("h"), PSTR("1")); @@ -2421,7 +2515,9 @@ void WifiSaveSettings(void) { ExecuteWebCommand((char*)cmnd.c_str()); } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleLoggingConfiguration +\*********************************************************************************************/ void HandleLoggingConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -2460,6 +2556,8 @@ void HandleLoggingConfiguration(void) { WSContentStop(); } +/*-------------------------------------------------------------------------------------------*/ + void LoggingSaveSettings(void) { String cmnd = F(D_CMND_BACKLOG "0 "); cmnd += AddWebCommand(PSTR(D_CMND_SERIALLOG), PSTR("l0"), STR(SERIAL_LOG_LEVEL)); @@ -2472,7 +2570,9 @@ void LoggingSaveSettings(void) { ExecuteWebCommand((char*)cmnd.c_str()); } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleLoggingConfiguration +\*********************************************************************************************/ void HandleOtherConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -2536,6 +2636,8 @@ void HandleOtherConfiguration(void) { WSContentStop(); } +/*-------------------------------------------------------------------------------------------*/ + void OtherSaveSettings(void) { String cmnd = F(D_CMND_BACKLOG "0 "); cmnd += AddWebCommand(PSTR(D_CMND_WEBPASSWORD "2"), PSTR("wp"), PSTR("\"")); @@ -2566,10 +2668,11 @@ void OtherSaveSettings(void) { ExecuteWebCommand((char*)cmnd.c_str()); } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleBackupConfiguration +\*********************************************************************************************/ -void HandleBackupConfiguration(void) -{ +void HandleBackupConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_BACKUP_CONFIGURATION)); @@ -2590,10 +2693,11 @@ void HandleBackupConfiguration(void) SettingsBufferFree(); } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleResetConfiguration +\*********************************************************************************************/ -void HandleResetConfiguration(void) -{ +void HandleResetConfiguration(void) { if (!HttpCheckPriviledgedAccess(!WifiIsInManagerMode())) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESET_CONFIGURATION)); @@ -2610,8 +2714,11 @@ void HandleResetConfiguration(void) ExecuteWebCommand(command); } -void HandleRestoreConfiguration(void) -{ +/*********************************************************************************************\ + * HandleRestoreConfiguration +\*********************************************************************************************/ + +void HandleRestoreConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTORE_CONFIGURATION)); @@ -2630,6 +2737,10 @@ void HandleRestoreConfiguration(void) Web.upload_file_type = UPL_SETTINGS; } +/*********************************************************************************************\ + * HandleInformation +\*********************************************************************************************/ + void WSContentSeparatorI(uint32_t size) { WSContentSend_P(PSTR("
"), (1 == size)?" size=1":""); // WSContentSend_P(PSTR("
"), size); @@ -2637,16 +2748,22 @@ void WSContentSeparatorI(uint32_t size) { // WSContentSend_P(PSTR(""), size); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSeparatorIFat(void) { // WSContentSend_P(PSTR("}1}2 ")); // Empty line =   WSContentSeparatorI(2); } +/*-------------------------------------------------------------------------------------------*/ + void WSContentSeparatorIThin(void) { // WSContentSend_P(PSTR("}1
}2
")); //

WSContentSeparatorI(1); } +/*-------------------------------------------------------------------------------------------*/ + void HandleInformation(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -2883,7 +3000,9 @@ void HandleInformation(void) { #endif // Not FIRMWARE_MINIMAL -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleUpgradeFirmware +\*********************************************************************************************/ #if defined(USE_ZIGBEE_EZSP) || defined(USE_TASMOTA_CLIENT) || defined(SHELLY_FW_UPGRADE) || defined(USE_RF_FLASH) || defined(USE_CCLOADER) #define USE_WEB_FW_UPGRADE @@ -2899,6 +3018,8 @@ struct { bool ready; } BUpload; +/*-------------------------------------------------------------------------------------------*/ + void BUploadInit(uint32_t file_type) { Web.upload_file_type = file_type; BUpload.spi_hex_size = 0; @@ -2908,6 +3029,8 @@ void BUploadInit(uint32_t file_type) { BUpload.ready = false; } +/*-------------------------------------------------------------------------------------------*/ + uint32_t BUploadWriteBuffer(uint8_t *buf, size_t size) { if (0 == BUpload.spi_sector_cursor) { // Starting a new sector write so we need to erase it first if (!ESP.flashEraseSector(BUpload.spi_sector_counter)) { @@ -2931,6 +3054,8 @@ uint32_t BUploadWriteBuffer(uint8_t *buf, size_t size) { #endif // USE_WEB_FW_UPGRADE +/*-------------------------------------------------------------------------------------------*/ + void HandleUpgradeFirmware(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -2954,6 +3079,8 @@ void HandleUpgradeFirmware(void) { Web.upload_file_type = UPL_TASMOTA; } +/*-------------------------------------------------------------------------------------------*/ + void HandleUpgradeFirmwareStart(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -2981,6 +3108,8 @@ void HandleUpgradeFirmwareStart(void) { ExecuteWebCommand(command); } +/*-------------------------------------------------------------------------------------------*/ + void HandleUploadDone(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -3029,6 +3158,8 @@ void HandleUploadDone(void) { WSContentStop(); } +/*-------------------------------------------------------------------------------------------*/ + void UploadServices(uint32_t start_service) { if (Web.upload_services_stopped != start_service) { return; } Web.upload_services_stopped = !start_service; @@ -3053,6 +3184,8 @@ void UploadServices(uint32_t start_service) { } } +/*-------------------------------------------------------------------------------------------*/ + void HandleUploadLoop(void) { // Based on ESP8266HTTPUpdateServer.cpp uses ESP8266WebServer Parsing.cpp and Cores Updater.cpp (Update) static uint32_t upload_size; @@ -3305,10 +3438,11 @@ void HandleUploadLoop(void) { // Scheduler(); // Feed OsWatch timer to prevent restart on long uploads } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandlePreflightRequest +\*********************************************************************************************/ -void HandlePreflightRequest(void) -{ +void HandlePreflightRequest(void) { #ifdef USE_CORS HttpHeaderCors(); #endif @@ -3317,9 +3451,11 @@ void HandlePreflightRequest(void) WSSend(200, CT_HTML, ""); } -/*-------------------------------------------------------------------------------------------*/ - #ifdef ESP32 +/*********************************************************************************************\ + * HandleSwitchBootPartition +\*********************************************************************************************/ + // Switch boot partition // // Parameter `u4` is either `fct` or `ota` to switch to factory or ota @@ -3338,8 +3474,9 @@ static void WSReturnSimpleString(const char *msg) { Webserver->send(200, "text/plain", msg); } -void HandleSwitchBootPartition(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void HandleSwitchBootPartition(void) { if (!HttpCheckPriviledgedAccess()) { return; } char tmp1[8]; @@ -3393,10 +3530,11 @@ void HandleSwitchBootPartition(void) } #endif // ESP32 -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleHttpCommand +\*********************************************************************************************/ -void HandleHttpCommand(void) -{ +void HandleHttpCommand(void) { if (!HttpCheckPriviledgedAccess(false)) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND)); @@ -3451,10 +3589,11 @@ void HandleHttpCommand(void) WSContentEnd(); } -/*-------------------------------------------------------------------------------------------*/ +/*********************************************************************************************\ + * HandleManagement +\*********************************************************************************************/ -void HandleManagement(void) -{ +void HandleManagement(void) { if (!HttpCheckPriviledgedAccess()) { return; } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_MANAGEMENT)); @@ -3473,8 +3612,11 @@ void HandleManagement(void) WSContentStop(); } -void HandleConsole(void) -{ +/*********************************************************************************************\ + * HandleConsole +\*********************************************************************************************/ + +void HandleConsole(void) { if (!HttpCheckPriviledgedAccess()) { return; } if (Webserver->hasArg(F("c2"))) { // Console refresh requested @@ -3496,8 +3638,9 @@ void HandleConsole(void) WSContentStop(); } -void HandleConsoleRefresh(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void HandleConsoleRefresh(void) { String svalue = Webserver->arg(F("c1")); if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), svalue.c_str()); @@ -3529,8 +3672,7 @@ void HandleConsoleRefresh(void) /********************************************************************************************/ -void HandleNotFound(void) -{ +void HandleNotFound(void) { // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), Webserver->uri().c_str()); #ifndef NO_CAPTIVE_PORTAL if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the error page. @@ -3554,10 +3696,11 @@ void HandleNotFound(void) } } +/********************************************************************************************/ + #ifndef NO_CAPTIVE_PORTAL /* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */ -bool CaptivePortal(void) -{ +bool CaptivePortal(void) { // Possible hostHeader: connectivitycheck.gstatic.com or 192.168.4.1 if ((WifiIsInManagerMode()) && !ValidIpAddress(Webserver->hostHeader().c_str())) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED)); @@ -3571,7 +3714,9 @@ bool CaptivePortal(void) } #endif // NO_CAPTIVE_PORTAL -/*********************************************************************************************/ +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ #ifndef FIRMWARE_MINIMAL @@ -3579,12 +3724,13 @@ enum {QUERY_DEFAULT=0, QUERY_RUN}; int WebQuery(char *buffer, int query_function); #ifdef USE_WEBRUN +/*-------------------------------------------------------------------------------------------*/ + char *WebRunBuffer = nullptr; char *WebRunContext = nullptr; bool WebRunMutex = false; -void WebRunLoop(void) -{ +void WebRunLoop(void) { if (WebRunBuffer && !WebRunMutex && BACKLOG_EMPTY) { WebRunMutex = true; char *command = strtok_r(WebRunContext, "\n\r", &WebRunContext); @@ -3600,8 +3746,9 @@ void WebRunLoop(void) } } -void WebRunInit(const char *command_buffer) -{ +/*-------------------------------------------------------------------------------------------*/ + +void WebRunInit(const char *command_buffer) { if (!WebRunBuffer) { int len = strlen(command_buffer); WebRunContext = WebRunBuffer = (char*)malloc(len+1); @@ -3617,9 +3764,9 @@ void WebRunInit(const char *command_buffer) } #endif // #ifdef USE_WEBRUN +/*-------------------------------------------------------------------------------------------*/ -int WebQuery(char *buffer, int query_function = 0) -{ +int WebQuery(char *buffer, int query_function = 0) { // http://192.168.1.1/path GET -> Sends HTTP GET http://192.168.1.1/path // http://192.168.1.1/path POST {"some":"message"} -> Sends HTTP POST to http://192.168.1.1/path with body {"some":"message"} // http://192.168.1.1/path PUT [Autorization: Bearer abcdxyz] potato -> Sends HTTP PUT to http://192.168.1.1/path with authorization header and body "potato" @@ -3737,147 +3884,8 @@ int WebQuery(char *buffer, int query_function = 0) return status; } -int WebSend(char *buffer) -{ - // [tasmota] POWER1 ON --> Sends http://tasmota/cm?cmnd=POWER1 ON - // [192.168.178.86:80,admin:joker] POWER1 ON --> Sends http://hostname:80/cm?user=admin&password=joker&cmnd=POWER1 ON - // [tasmota] /any/link/starting/with/a/slash.php?log=123 --> Sends http://tasmota/any/link/starting/with/a/slash.php?log=123 - // [tasmota,admin:joker] /any/link/starting/with/a/slash.php?log=123 --> Sends http://tasmota/any/link/starting/with/a/slash.php?log=123 - char *host; - char *user; - char *password; - char *command; - int status = WEBCMND_WRONG_PARAMETERS; - - // buffer = | [ 192.168.178.86 : 80 , admin : joker ] POWER1 ON | - host = strtok_r(buffer, "]", &command); // host = | [ 192.168.178.86 : 80 , admin : joker |, command = | POWER1 ON | - if (host && command) { - RemoveSpace(host); // host = |[192.168.178.86:80,admin:joker| - host++; // host = |192.168.178.86:80,admin:joker| - Skip [ - host = strtok_r(host, ",", &user); // host = |192.168.178.86:80|, user = |admin:joker| - String url = F("http://"); // url = |http://| - url += host; // url = |http://192.168.178.86:80| - - command = Trim(command); // command = |POWER1 ON| or |/any/link/starting/with/a/slash.php?log=123| - if (command[0] != '/') { - url += F("/cm?"); // url = |http://192.168.178.86/cm?| - if (user) { - user = strtok_r(user, ":", &password); // user = |admin|, password = |joker| - if (user && password) { - char userpass[200]; - snprintf_P(userpass, sizeof(userpass), PSTR("user=%s&password=%s&"), user, password); - url += userpass; // url = |http://192.168.178.86/cm?user=admin&password=joker&| - } - } - url += F("cmnd="); // url = |http://192.168.178.86/cm?cmnd=| or |http://192.168.178.86/cm?user=admin&password=joker&cmnd=| - } - url += UrlEncode(command); // url = |http://192.168.178.86/cm?cmnd=POWER1%20ON| - url += F(" GET"); // url = |http://192.168.178.86/cm?cmnd=POWER1%20ON GET| - - DEBUG_CORE_LOG(PSTR("WEB: Uri '%s'"), url.c_str()); - status = WebQuery(const_cast(url.c_str())); - } - return status; -} - -#ifdef USE_WEBGETCONFIG -int WebGetConfig(char *buffer) { - // http://user:password@server:port/path/%id%.dmp : %id% will be expanded to MAC address - - int status = WEBCMND_WRONG_PARAMETERS; - - RemoveSpace(buffer); // host = |[192.168.178.86:80,admin:joker| - String url = ResolveToken(buffer); - - DEBUG_CORE_LOG(PSTR("WEB: Config Uri '%s'"), url.c_str()); - - -#if defined(ESP32) && defined(USE_WEBCLIENT_HTTPS) - HTTPClientLight http; - if (http.begin(UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| -#else // HTTP only - WiFiClient http_client; - HTTPClient http; - if (http.begin(http_client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| -#endif - int http_code = http.GET(); // Start connection and send HTTP header - if (http_code > 0) { // http_code will be negative on error - status = WEBCMND_DONE; - if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) { - WiFiClient *stream = http.getStreamPtr(); - int len = http.getSize(); - if (len <= sizeof(TSettings)) { - len = sizeof(TSettings); - } - if (SettingsBufferAlloc(len)) { - uint8_t *buff = settings_buffer; - while (http.connected() && (len > 0)) { - size_t size = stream->available(); - if (size) { - int read = stream->readBytes(buff, len); - len -= read; - } - delayMicroseconds(1); - } - if (len) { - DEBUG_CORE_LOG(PSTR("WEB: Connection lost")); - status = WEBCMND_CONNECTION_LOST; - } else if (SettingsConfigRestore()) { - AddLog(LOG_LEVEL_INFO, PSTR("WEB: Settings applied, restarting")); - TasmotaGlobal.restart_flag = 2; // Always restart to re-enable disabled features during update - } else { - DEBUG_CORE_LOG(PSTR("WEB: Settings file invalid")); - status = WEBCMND_INVALID_FILE; - } - } else { - DEBUG_CORE_LOG(PSTR("WEB: Memory error (%d) or invalid file length (%d)"), settings_buffer, len); - status = WEBCMND_MEMORY_ERROR; - } - } else { - AddLog(LOG_LEVEL_DEBUG, PSTR("WEB: HTTP error %d"), http_code); - status = (http_code == HTTP_CODE_NOT_FOUND) ? WEBCMND_FILE_NOT_FOUND : WEBCMND_OTHER_HTTP_ERROR; - } - } else { - DEBUG_CORE_LOG(PSTR("WEB: Connection failed")); - status = 2; // Connection failed - } - http.end(); // Clean up connection data - } else { - status = 3; // Host not found or connection error - } - - return status; -} -#endif // USE_WEBGETCONFIG - -bool JsonWebColor(const char* dataBuf) -{ - // Default (Dark theme) - // {"WebColor":["#eaeaea","#252525","#4f4f4f","#000","#ddd","#65c115","#1f1f1f","#ff5661","#008000","#faffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#faffff","#999","#eaeaea","#08405e"]} - // Default pre v7 (Light theme) - // {"WebColor":["#000","#fff","#f2f2f2","#000","#fff","#000","#fff","#f00","#008000","#fff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#fff","#999","#000","#08405e"]} // {"WebColor":["#000000","#ffffff","#f2f2f2","#000000","#ffffff","#000000","#ffffff","#ff0000","#008000","#ffffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#ffffff","#999999","#000000","#08405e"]} - - JsonParser parser((char*) dataBuf); - JsonParserObject root = parser.getRootObject(); - JsonParserArray arr = root[PSTR(D_CMND_WEBCOLOR)].getArray(); - if (arr) { // if arr is valid, i.e. json is valid, the key D_CMND_WEBCOLOR was found and the token is an arra - uint32_t i = 0; - for (auto color : arr) { - if (i < COL_LAST) { - WebHexCode(i, color.getStr()); - } else { - break; - } - i++; - } - } - return true; -} - -/*********************************************************************************************\ - * Commands -\*********************************************************************************************/ +/*-------------------------------------------------------------------------------------------*/ const char kWebCmndStatus[] PROGMEM = D_JSON_DONE "|" D_JSON_WRONG_PARAMETERS "|" D_JSON_CONNECT_FAILED "|" D_JSON_HOST_NOT_FOUND "|" D_JSON_MEMORY_ERROR "|" #ifdef USE_WEBGETCONFIG @@ -3951,8 +3959,9 @@ void CmndWebTime(void) { } #ifdef USE_EMULATION -void CmndEmulation(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void CmndEmulation(void) { #if defined(USE_EMULATION_WEMO) || defined(USE_EMULATION_HUE) #if defined(USE_EMULATION_WEMO) && defined(USE_EMULATION_HUE) if ((XdrvMailbox.payload >= EMUL_NONE) && (XdrvMailbox.payload < EMUL_MAX)) { @@ -3973,6 +3982,8 @@ void CmndEmulation(void) #endif // USE_EMULATION #ifdef USE_SENDMAIL +/*-------------------------------------------------------------------------------------------*/ + void CmndSendmail(void) { if (XdrvMailbox.data_len > 0) { uint8_t result = SendMail(XdrvMailbox.data); @@ -3982,8 +3993,9 @@ void CmndSendmail(void) { } #endif // USE_SENDMAIL -void CmndWebServer(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void CmndWebServer(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { Settings->webserver = XdrvMailbox.payload; } @@ -3995,8 +4007,9 @@ void CmndWebServer(void) } } -void CmndWebPassword(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void CmndWebPassword(void) { bool show_asterisk = (2 == XdrvMailbox.index); if (XdrvMailbox.data_len > 0) { SettingsUpdateText(SET_WEBPWD, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? WEB_PASSWORD : XdrvMailbox.data); @@ -4011,24 +4024,72 @@ void CmndWebPassword(void) } } -void CmndWeblog(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void CmndWeblog(void) { if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) { Settings->weblog_level = XdrvMailbox.payload; } ResponseCmndNumber(Settings->weblog_level); } -void CmndWebRefresh(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void CmndWebRefresh(void) { if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload <= 65000)) { Settings->web_refresh = XdrvMailbox.payload; } ResponseCmndNumber(Settings->web_refresh); } -void CmndWebSend(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +int WebSend(char *buffer) { + // [tasmota] POWER1 ON --> Sends http://tasmota/cm?cmnd=POWER1 ON + // [192.168.178.86:80,admin:joker] POWER1 ON --> Sends http://hostname:80/cm?user=admin&password=joker&cmnd=POWER1 ON + // [tasmota] /any/link/starting/with/a/slash.php?log=123 --> Sends http://tasmota/any/link/starting/with/a/slash.php?log=123 + // [tasmota,admin:joker] /any/link/starting/with/a/slash.php?log=123 --> Sends http://tasmota/any/link/starting/with/a/slash.php?log=123 + + char *host; + char *user; + char *password; + char *command; + int status = WEBCMND_WRONG_PARAMETERS; + + // buffer = | [ 192.168.178.86 : 80 , admin : joker ] POWER1 ON | + host = strtok_r(buffer, "]", &command); // host = | [ 192.168.178.86 : 80 , admin : joker |, command = | POWER1 ON | + if (host && command) { + RemoveSpace(host); // host = |[192.168.178.86:80,admin:joker| + host++; // host = |192.168.178.86:80,admin:joker| - Skip [ + host = strtok_r(host, ",", &user); // host = |192.168.178.86:80|, user = |admin:joker| + String url = F("http://"); // url = |http://| + url += host; // url = |http://192.168.178.86:80| + + command = Trim(command); // command = |POWER1 ON| or |/any/link/starting/with/a/slash.php?log=123| + if (command[0] != '/') { + url += F("/cm?"); // url = |http://192.168.178.86/cm?| + if (user) { + user = strtok_r(user, ":", &password); // user = |admin|, password = |joker| + if (user && password) { + char userpass[200]; + snprintf_P(userpass, sizeof(userpass), PSTR("user=%s&password=%s&"), user, password); + url += userpass; // url = |http://192.168.178.86/cm?user=admin&password=joker&| + } + } + url += F("cmnd="); // url = |http://192.168.178.86/cm?cmnd=| or |http://192.168.178.86/cm?user=admin&password=joker&cmnd=| + } + url += UrlEncode(command); // url = |http://192.168.178.86/cm?cmnd=POWER1%20ON| + url += F(" GET"); // url = |http://192.168.178.86/cm?cmnd=POWER1%20ON GET| + + DEBUG_CORE_LOG(PSTR("WEB: Uri '%s'"), url.c_str()); + status = WebQuery(const_cast(url.c_str())); + } + return status; +} + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + +void CmndWebSend(void) { if (XdrvMailbox.data_len > 0) { uint32_t result = WebSend(XdrvMailbox.data); if (result != WEBCMND_VALID_RESPONSE) { @@ -4038,6 +4099,8 @@ void CmndWebSend(void) } } +/*-------------------------------------------------------------------------------------------*/ + void CmndWebQuery(void) { if (XdrvMailbox.data_len > 0) { uint32_t result = WebQuery(XdrvMailbox.data); @@ -4049,6 +4112,8 @@ void CmndWebQuery(void) { } #ifdef USE_WEBRUN +/*-------------------------------------------------------------------------------------------*/ + void CmndWebRun(void) { if (XdrvMailbox.data_len > 0) { uint32_t result = WebQuery(XdrvMailbox.data, QUERY_RUN); @@ -4061,6 +4126,78 @@ void CmndWebRun(void) { #endif // #ifdef USE_WEBRUN #ifdef USE_WEBGETCONFIG +/*-------------------------------------------------------------------------------------------*/ + +int WebGetConfig(char *buffer) { + // http://user:password@server:port/path/%id%.dmp : %id% will be expanded to MAC address + + int status = WEBCMND_WRONG_PARAMETERS; + + RemoveSpace(buffer); // host = |[192.168.178.86:80,admin:joker| + String url = ResolveToken(buffer); + + DEBUG_CORE_LOG(PSTR("WEB: Config Uri '%s'"), url.c_str()); + + +#if defined(ESP32) && defined(USE_WEBCLIENT_HTTPS) + HTTPClientLight http; + if (http.begin(UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| +#else // HTTP only + WiFiClient http_client; + HTTPClient http; + if (http.begin(http_client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| +#endif + int http_code = http.GET(); // Start connection and send HTTP header + if (http_code > 0) { // http_code will be negative on error + status = WEBCMND_DONE; + if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) { + WiFiClient *stream = http.getStreamPtr(); + int len = http.getSize(); + if (len <= sizeof(TSettings)) { + len = sizeof(TSettings); + } + if (SettingsBufferAlloc(len)) { + uint8_t *buff = settings_buffer; + while (http.connected() && (len > 0)) { + size_t size = stream->available(); + if (size) { + int read = stream->readBytes(buff, len); + len -= read; + } + delayMicroseconds(1); + } + if (len) { + DEBUG_CORE_LOG(PSTR("WEB: Connection lost")); + status = WEBCMND_CONNECTION_LOST; + } else if (SettingsConfigRestore()) { + AddLog(LOG_LEVEL_INFO, PSTR("WEB: Settings applied, restarting")); + TasmotaGlobal.restart_flag = 2; // Always restart to re-enable disabled features during update + } else { + DEBUG_CORE_LOG(PSTR("WEB: Settings file invalid")); + status = WEBCMND_INVALID_FILE; + } + } else { + DEBUG_CORE_LOG(PSTR("WEB: Memory error (%d) or invalid file length (%d)"), settings_buffer, len); + status = WEBCMND_MEMORY_ERROR; + } + } else { + AddLog(LOG_LEVEL_DEBUG, PSTR("WEB: HTTP error %d"), http_code); + status = (http_code == HTTP_CODE_NOT_FOUND) ? WEBCMND_FILE_NOT_FOUND : WEBCMND_OTHER_HTTP_ERROR; + } + } else { + DEBUG_CORE_LOG(PSTR("WEB: Connection failed")); + status = 2; // Connection failed + } + http.end(); // Clean up connection data + } else { + status = 3; // Host not found or connection error + } + + return status; +} + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + void CmndWebGetConfig(void) { // WebGetConfig http://myserver:8000/tasmota/conf/%id%.dmp where %id% is expanded to device mac address // WebGetConfig http://myserver:8000/tasmota/conf/Config_demo_9.5.0.8.dmp @@ -4072,8 +4209,35 @@ void CmndWebGetConfig(void) { } #endif // USE_WEBGETCONFIG -void CmndWebColor(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +bool JsonWebColor(const char* dataBuf) { + // Default (Dark theme) + // {"WebColor":["#eaeaea","#252525","#4f4f4f","#000","#ddd","#65c115","#1f1f1f","#ff5661","#008000","#faffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#faffff","#999","#eaeaea","#08405e"]} + // Default pre v7 (Light theme) + // {"WebColor":["#000","#fff","#f2f2f2","#000","#fff","#000","#fff","#f00","#008000","#fff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#fff","#999","#000","#08405e"]} + // {"WebColor":["#000000","#ffffff","#f2f2f2","#000000","#ffffff","#000000","#ffffff","#ff0000","#008000","#ffffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#ffffff","#999999","#000000","#08405e"]} + + JsonParser parser((char*) dataBuf); + JsonParserObject root = parser.getRootObject(); + JsonParserArray arr = root[PSTR(D_CMND_WEBCOLOR)].getArray(); + if (arr) { // if arr is valid, i.e. json is valid, the key D_CMND_WEBCOLOR was found and the token is an arra + uint32_t i = 0; + for (auto color : arr) { + if (i < COL_LAST) { + WebHexCode(i, color.getStr()); + } else { + break; + } + i++; + } + } + return true; +} + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + +void CmndWebColor(void) { if (XdrvMailbox.data_len > 0) { if (strchr(XdrvMailbox.data, '{') == nullptr) { // If no JSON it must be parameter if ((XdrvMailbox.data_len > 3) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= COL_LAST)) { @@ -4096,8 +4260,9 @@ void CmndWebColor(void) ResponseAppend_P(PSTR("]}")); } -void CmndWebSensor(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void CmndWebSensor(void) { if (XdrvMailbox.index < MAX_XSNS_DRIVERS) { if (XdrvMailbox.payload >= 0) { bitWrite(Settings->sensors[1][XdrvMailbox.index / 32], XdrvMailbox.index % 32, XdrvMailbox.payload &1); @@ -4108,6 +4273,8 @@ void CmndWebSensor(void) ResponseJsonEnd(); } +/*-------------------------------------------------------------------------------------------*/ + String *WebButton1732[16] = {0,}; void SetWebButton(uint8_t button_index, const char *text) { @@ -4134,8 +4301,7 @@ const char* GetWebButton(uint8_t button_index) { return empty; } -void CmndWebButton(void) -{ +void CmndWebButton(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_BUTTON_TEXT)) { if (!XdrvMailbox.usridx) { ResponseCmndAll(SET_BUTTON1, MAX_BUTTON_TEXT); @@ -4148,6 +4314,8 @@ void CmndWebButton(void) } } +/*-------------------------------------------------------------------------------------------*/ + void CmndWebCanvas(void) { /* WebCanvas allows GUI body canvas configuration using a color, "url" or "gradient". @@ -4172,8 +4340,9 @@ void CmndWebCanvas(void) { } #ifdef USE_CORS -void CmndCors(void) -{ +/*-------------------------------------------------------------------------------------------*/ + +void CmndCors(void) { if (XdrvMailbox.data_len > 0) { SettingsUpdateText(SET_CORS, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? CORS_DOMAIN : XdrvMailbox.data); } @@ -4187,8 +4356,7 @@ void CmndCors(void) * Interface \*********************************************************************************************/ -bool Xdrv01(uint32_t function) -{ +bool Xdrv01(uint32_t function) { bool result = false; switch (function) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino index 252b6048e..ddc1c679a 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino @@ -272,6 +272,8 @@ #define DALI_TOPIC "DALI" #define D_PRFX_DALI "Dali" +/*********************************************************************************************/ + const char kDALICommands[] PROGMEM = D_PRFX_DALI "|" // Prefix "|" D_CMND_POWER "|" D_CMND_DIMMER "|Target" #ifdef USE_LIGHT @@ -292,7 +294,6 @@ struct DALI { uint32_t bit_cycles; uint32_t last_activity; uint32_t received_dali_data; // Data received from DALI bus - uint32_t slider_update_time; uint8_t pin_rx; uint8_t pin_tx; uint8_t max_short_address; @@ -348,6 +349,8 @@ uint32_t DaliAddress2Target(uint32_t adr) { } */ +/*-------------------------------------------------------------------------------------------*/ + uint32_t DaliSaveState(uint32_t adr, uint32_t cmd) { if (adr &0x01) { return 0; } // No address int index = -1; @@ -376,6 +379,8 @@ uint32_t DaliSaveState(uint32_t adr, uint32_t cmd) { return index; } +/*-------------------------------------------------------------------------------------------*/ + void DaliEnableRxInterrupt(void) { Dali->available = false; attachInterrupt(Dali->pin_rx, DaliReceiveData, (Dali->invert_rx) ? RISING : FALLING); @@ -639,6 +644,8 @@ bool DaliSetPowerOnLevel(uint32_t adr, uint32_t v) { return DaliSetValue(adr, DALI_QUERY_POWER_ON_LEVEL, DALI_SET_POWER_ON_LEVEL, v); } +/*-------------------------------------------------------------------------------------------*/ + uint32_t DaliGearPresent(void) { uint32_t count = 0; for (uint32_t sa = 0; sa < Dali->max_short_address; sa++) { // Scanning 64 addresses takes about 2500 ms @@ -649,6 +656,8 @@ uint32_t DaliGearPresent(void) { return count; } +/*-------------------------------------------------------------------------------------------*/ + void DaliInitLight(void) { // Taken from Shelly Dali Dimmer ;-) DaliSendData(DALI_DATA_TRANSFER_REGISTER0, DALI_INIT_FADE); // Fade x second @@ -1002,6 +1011,8 @@ bool DaliJsonParse(void) { return served; } +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + void CmndDali(void) { // Dali {"addr":254,"cmd":100} - Any address and/or command // Dali 0|1 - Enable DALI receive probe @@ -1031,6 +1042,8 @@ void CmndDaliTarget(void) { ResponseCmndNumber(Dali->target); } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliPower(void) { // DaliPower 0 - Broadcast power off // DaliPower 1 - Broadcast power on to last dimmer state @@ -1068,6 +1081,8 @@ void CmndDaliPower(void) { ResponseDali(index); } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliDimmer(void) { // DaliDimmer 0..100 - Broadcast set power off or dimmer state // DaliDimmer0 0..100 - Broadcast set power off or dimmer state @@ -1094,6 +1109,8 @@ void CmndDaliDimmer(void) { ResponseDali(index); } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliGroup(void) { // DaliGroup1 1,2 - Add device 1 and 2 to group 1 // DaliGroup1 -1,2 - Remove device 1 and 2 to group 1 @@ -1151,6 +1168,8 @@ void CmndDaliGroup(void) { } } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliGear(void) { if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 64)) { Dali->max_short_address = XdrvMailbox.payload; @@ -1160,6 +1179,8 @@ void CmndDaliGear(void) { ResponseAppend_P(PSTR("%d,\"Present\":%d}"), Dali->max_short_address, count); } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliSend(void) { // Send command // Setting bit 8 will repeat command once @@ -1180,6 +1201,8 @@ void CmndDaliSend(void) { } } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliQuery(void) { // Send command and return response or -1 (no response within DALI_TIMEOUT) // Setting bit 8 will repeat command once @@ -1193,6 +1216,8 @@ void CmndDaliQuery(void) { } } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliScan(void) { // Scan short addresses // DaliScan 1 - Reset and commission short addresses @@ -1207,6 +1232,8 @@ void CmndDaliScan(void) { } } +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliGroupSliders(void) { // DaliGroupSliders 0..16 - Add group sliders if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 16)) { @@ -1217,6 +1244,8 @@ void CmndDaliGroupSliders(void) { } #ifdef USE_LIGHT +/*-------------------------------------------------------------------------------------------*/ + void CmndDaliLight(void) { // DaliLight 0 - Disable light controls // DaliLight 1 - Enable light controls @@ -1259,6 +1288,8 @@ void DaliWebAddMainSlider(void) { WSContentSend_P(PSTR("")); } +/*********************************************************************************************/ + void DaliWebGetArg(void) { char tmp[8]; // WebGetArg numbers only char svalue[32]; // Command and number parameter @@ -1283,41 +1314,29 @@ void DaliWebGetArg(void) { ExecuteWebCommand(svalue); } } -#endif // USE_WEBSERVER -void DaliShow(bool json) { - if (json) { - ResponseAppend_P(PSTR(",")); - ResponseAppendDali(0); -#ifdef USE_WEBSERVER - } else { - WSContentSend_P(PSTR("")); // Terminate current {t} - WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { // DaliLight 0/1, DaliGroupSliders - WSContentSend_P(PSTR("eb('k75%d').style='background:#%06x';"), - i, WebColor((Dali->power[i]) ? COL_BUTTON : COL_BUTTON_OFF)); - if (Dali->dimmer[i] != Dali->web_dimmer[i]) { - if (0 == Dali->slider_update_time) { - Dali->slider_update_time = slider_update_time + Settings->web_refresh; // Allow other users to sync screen - } - else if (slider_update_time > Dali->slider_update_time) { - Dali->slider_update_time = 1; // Allow multiple updates - Dali->web_dimmer[i] = Dali->dimmer[i]; - } - WSContentSend_P(PSTR("eb('i75%d').value='%d';"), - i, changeUIntScale(Dali->dimmer[i], 0, 254, 0, 100)); +/*********************************************************************************************/ + +void DaliWebShow(void) { + WSContentSend_P(PSTR("")); // Terminate current {t} + WSContentSend_P(HTTP_MSG_EXEC_JAVASCRIPT); // "sbflag1.dali_light; i <= Settings->mbflag2.dali_group_sliders; i++) { // DaliLight 0/1, DaliGroupSliders + WSContentSend_P(PSTR("eb('k75%d').style='background:#%06x';"), + i, WebColor((Dali->power[i]) ? COL_BUTTON : COL_BUTTON_OFF)); + if (Dali->dimmer[i] != Dali->web_dimmer[i]) { + if (WebUpdateSliderTime()) { + Dali->web_dimmer[i] = Dali->dimmer[i]; } + WSContentSend_P(PSTR("eb('i75%d').value='%d';"), + i, changeUIntScale(Dali->dimmer[i], 0, 254, 0, 100)); } - if (1 == Dali->slider_update_time) { - Dali->slider_update_time = 0; - } - WSContentSend_P(PSTR("\">{t}")); // Restart {t} = - WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) -#endif // USE_WEBSERVER } + WSContentSend_P(PSTR("\">{t}")); // Restart {t} =
+ WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1) } +#endif // USE_WEBSERVER + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -1345,11 +1364,12 @@ bool Xdrv75(uint32_t function) { break; #endif // USE_LIGHT case FUNC_JSON_APPEND: - DaliShow(true); + ResponseAppend_P(PSTR(",")); + ResponseAppendDali(0); break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: - DaliShow(false); + DaliWebShow(); break; case FUNC_WEB_ADD_MAIN_BUTTON: DaliWebAddMainSlider(); From 77f9fb07834755da57db8b82cae273fad626b213 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:35:53 +0100 Subject: [PATCH 119/205] Matter provisioning with matter.js controller (#22470) --- CHANGELOG.md | 1 + .../src/embedded/Matter_IM_Message.be | 4 +- .../src/embedded/Matter_Message.be | 4 +- .../solidify/solidified_Matter_IM_Message.h | 2 +- .../src/solidify/solidified_Matter_Message.h | 188 +++++++++--------- 5 files changed, 100 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8644d97b..4f358a9d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. ### Changed ### Fixed +- Matter provisioning with matter.js controller ### Removed diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be b/lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be index 7559236e1..f19fe20bd 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be @@ -197,8 +197,8 @@ matter.IM_WriteResponse = Matter_IM_WriteResponse # This version pull the attributes in lazy mode, only when response is computed ################################################################################# class Matter_IM_ReportData_Pull : Matter_IM_Message - static var MAX_MESSAGE = 1200 # max bytes size for a single TLV worklaod - # the maximum MTU is 1280, which leaves 80 bytes for the rest of the message + static var MAX_MESSAGE = 1150 # max bytes size for a single TLV worklaod + # the maximum MTU is 1280, which leaves 130 bytes for the rest of the message # section 4.4.4 (p. 114) # note: `self.data` (bytes or nil) is containing any remaining responses that could not fit in previous packets var generator_or_arr # a PathGenerator or an array of PathGenerator diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Message.be b/lib/libesp32/berry_matter/src/embedded/Matter_Message.be index 1d418dfc0..4291fd64a 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Message.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Message.be @@ -375,7 +375,7 @@ class Matter_Frame # recompute nonce var n = self.message_handler._n_bytes # use cached bytes() object to avoid allocation n.clear() - n.add(self.flags, 1) + n.add(self.sec_flags, 1) n.add(self.message_counter, 4) if self.source_node_id n .. self.source_node_id @@ -426,7 +426,7 @@ class Matter_Frame # recompute nonce var n = self.message_handler._n_bytes # use cached bytes() object to avoid allocation n.clear() - n.add(self.flags, 1) + n.add(self.sec_flags, 1) n.add(self.message_counter, 4) if session.is_CASE() && session.get_device_id() n .. session.get_device_id() diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Message.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Message.h index 5e6fbfda6..6a0337ed1 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Message.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Message.h @@ -1095,7 +1095,7 @@ be_local_class(Matter_IM_ReportData_Pull, { be_const_key_weak(status_ok_received, -1), be_const_closure(class_Matter_IM_ReportData_Pull_status_ok_received_closure) }, { be_const_key_weak(data_ev, -1), be_const_var(4) }, { be_const_key_weak(suppress_response, 8), be_const_var(3) }, - { be_const_key_weak(MAX_MESSAGE, -1), be_const_int(1200) }, + { be_const_key_weak(MAX_MESSAGE, -1), be_const_int(1150) }, { be_const_key_weak(set_suppress_response, -1), be_const_closure(class_Matter_IM_ReportData_Pull_set_suppress_response_closure) }, { be_const_key_weak(set_subscription_id, -1), be_const_closure(class_Matter_IM_ReportData_Pull_set_subscription_id_closure) }, { be_const_key_weak(generator_or_arr, 5), be_const_var(0) }, diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Message.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Message.h index 90057f7d4..58559d111 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Message.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Message.h @@ -16,7 +16,7 @@ static const bvalue be_ktab_class_Matter_Frame[73] = { /* K7 */ be_nested_str_weak(_n_bytes), /* K8 */ be_nested_str_weak(clear), /* K9 */ be_nested_str_weak(add), - /* K10 */ be_nested_str_weak(flags), + /* K10 */ be_nested_str_weak(sec_flags), /* K11 */ be_const_int(1), /* K12 */ be_nested_str_weak(message_counter), /* K13 */ be_nested_str_weak(is_CASE), @@ -27,12 +27,12 @@ static const bvalue be_ktab_class_Matter_Frame[73] = { /* K18 */ be_const_int(0), /* K19 */ be_nested_str_weak(remote_ip), /* K20 */ be_nested_str_weak(remote_port), - /* K21 */ be_nested_str_weak(flag_s), - /* K22 */ be_nested_str_weak(flag_dsiz), - /* K23 */ be_const_int(3), - /* K24 */ be_nested_str_weak(local_session_id), - /* K25 */ be_const_int(2), - /* K26 */ be_nested_str_weak(sec_flags), + /* K21 */ be_nested_str_weak(flags), + /* K22 */ be_nested_str_weak(flag_s), + /* K23 */ be_nested_str_weak(flag_dsiz), + /* K24 */ be_const_int(3), + /* K25 */ be_nested_str_weak(local_session_id), + /* K26 */ be_const_int(2), /* K27 */ be_nested_str_weak(sec_p), /* K28 */ be_nested_str_weak(sec_c), /* K29 */ be_nested_str_weak(sec_sesstype), @@ -260,83 +260,83 @@ be_local_closure(class_Matter_Frame_encode_frame, /* name */ 0x00100805, // 000B ADD R4 R4 R5 0x7C0C0200, // 000C CALL R3 1 0x5C080600, // 000D MOVE R2 R3 - 0x880C010A, // 000E GETMBR R3 R0 K10 + 0x880C0115, // 000E GETMBR R3 R0 K21 0x4C100000, // 000F LDNIL R4 0x1C0C0604, // 0010 EQ R3 R3 R4 0x780E000D, // 0011 JMPF R3 #0020 - 0x90021512, // 0012 SETMBR R0 K10 K18 - 0x880C0115, // 0013 GETMBR R3 R0 K21 + 0x90022B12, // 0012 SETMBR R0 K21 K18 + 0x880C0116, // 0013 GETMBR R3 R0 K22 0x780E0003, // 0014 JMPF R3 #0019 - 0x880C010A, // 0015 GETMBR R3 R0 K10 + 0x880C0115, // 0015 GETMBR R3 R0 K21 0x54120003, // 0016 LDINT R4 4 0x300C0604, // 0017 OR R3 R3 R4 - 0x90021403, // 0018 SETMBR R0 K10 R3 - 0x880C0116, // 0019 GETMBR R3 R0 K22 + 0x90022A03, // 0018 SETMBR R0 K21 R3 + 0x880C0117, // 0019 GETMBR R3 R0 K23 0x780E0004, // 001A JMPF R3 #0020 - 0x880C010A, // 001B GETMBR R3 R0 K10 - 0x88100116, // 001C GETMBR R4 R0 K22 - 0x2C100917, // 001D AND R4 R4 K23 + 0x880C0115, // 001B GETMBR R3 R0 K21 + 0x88100117, // 001C GETMBR R4 R0 K23 + 0x2C100918, // 001D AND R4 R4 K24 0x300C0604, // 001E OR R3 R3 R4 - 0x90021403, // 001F SETMBR R0 K10 R3 + 0x90022A03, // 001F SETMBR R0 K21 R3 0x8C0C0509, // 0020 GETMET R3 R2 K9 - 0x8814010A, // 0021 GETMBR R5 R0 K10 + 0x88140115, // 0021 GETMBR R5 R0 K21 0x5818000B, // 0022 LDCONST R6 K11 0x7C0C0600, // 0023 CALL R3 3 0x8C0C0509, // 0024 GETMET R3 R2 K9 - 0x88140118, // 0025 GETMBR R5 R0 K24 + 0x88140119, // 0025 GETMBR R5 R0 K25 0x78160001, // 0026 JMPF R5 #0029 - 0x88140118, // 0027 GETMBR R5 R0 K24 + 0x88140119, // 0027 GETMBR R5 R0 K25 0x70020000, // 0028 JMP #002A 0x58140012, // 0029 LDCONST R5 K18 - 0x58180019, // 002A LDCONST R6 K25 + 0x5818001A, // 002A LDCONST R6 K26 0x7C0C0600, // 002B CALL R3 3 - 0x880C011A, // 002C GETMBR R3 R0 K26 + 0x880C010A, // 002C GETMBR R3 R0 K10 0x4C100000, // 002D LDNIL R4 0x1C0C0604, // 002E EQ R3 R3 R4 0x780E0013, // 002F JMPF R3 #0044 - 0x90023512, // 0030 SETMBR R0 K26 K18 + 0x90021512, // 0030 SETMBR R0 K10 K18 0x880C011B, // 0031 GETMBR R3 R0 K27 0x780E0003, // 0032 JMPF R3 #0037 - 0x880C011A, // 0033 GETMBR R3 R0 K26 + 0x880C010A, // 0033 GETMBR R3 R0 K10 0x5412007F, // 0034 LDINT R4 128 0x300C0604, // 0035 OR R3 R3 R4 - 0x90023403, // 0036 SETMBR R0 K26 R3 + 0x90021403, // 0036 SETMBR R0 K10 R3 0x880C011C, // 0037 GETMBR R3 R0 K28 0x780E0003, // 0038 JMPF R3 #003D - 0x880C011A, // 0039 GETMBR R3 R0 K26 + 0x880C010A, // 0039 GETMBR R3 R0 K10 0x5412003F, // 003A LDINT R4 64 0x300C0604, // 003B OR R3 R3 R4 - 0x90023403, // 003C SETMBR R0 K26 R3 + 0x90021403, // 003C SETMBR R0 K10 R3 0x880C011D, // 003D GETMBR R3 R0 K29 0x780E0004, // 003E JMPF R3 #0044 - 0x880C011A, // 003F GETMBR R3 R0 K26 + 0x880C010A, // 003F GETMBR R3 R0 K10 0x8810011D, // 0040 GETMBR R4 R0 K29 - 0x2C100917, // 0041 AND R4 R4 K23 + 0x2C100918, // 0041 AND R4 R4 K24 0x300C0604, // 0042 OR R3 R3 R4 - 0x90023403, // 0043 SETMBR R0 K26 R3 + 0x90021403, // 0043 SETMBR R0 K10 R3 0x8C0C0509, // 0044 GETMET R3 R2 K9 - 0x8814011A, // 0045 GETMBR R5 R0 K26 + 0x8814010A, // 0045 GETMBR R5 R0 K10 0x5818000B, // 0046 LDCONST R6 K11 0x7C0C0600, // 0047 CALL R3 3 0x8C0C0509, // 0048 GETMET R3 R2 K9 0x8814010C, // 0049 GETMBR R5 R0 K12 0x541A0003, // 004A LDINT R6 4 0x7C0C0600, // 004B CALL R3 3 - 0x880C0115, // 004C GETMBR R3 R0 K21 + 0x880C0116, // 004C GETMBR R3 R0 K22 0x780E0001, // 004D JMPF R3 #0050 0x880C011E, // 004E GETMBR R3 R0 K30 0x400C0403, // 004F CONNECT R3 R2 R3 - 0x880C0116, // 0050 GETMBR R3 R0 K22 + 0x880C0117, // 0050 GETMBR R3 R0 K23 0x1C0C070B, // 0051 EQ R3 R3 K11 0x780E0001, // 0052 JMPF R3 #0055 0x880C011F, // 0053 GETMBR R3 R0 K31 0x400C0403, // 0054 CONNECT R3 R2 R3 - 0x880C0116, // 0055 GETMBR R3 R0 K22 - 0x1C0C0719, // 0056 EQ R3 R3 K25 + 0x880C0117, // 0055 GETMBR R3 R0 K23 + 0x1C0C071A, // 0056 EQ R3 R3 K26 0x780E0003, // 0057 JMPF R3 #005C 0x8C0C0509, // 0058 GETMET R3 R2 K9 0x88140120, // 0059 GETMBR R5 R0 K32 - 0x58180019, // 005A LDCONST R6 K25 + 0x5818001A, // 005A LDCONST R6 K26 0x7C0C0600, // 005B CALL R3 3 0x600C000C, // 005C GETGBL R3 G12 0x5C100400, // 005D MOVE R4 R2 @@ -362,7 +362,7 @@ be_local_closure(class_Matter_Frame_encode_frame, /* name */ 0x880C0124, // 0071 GETMBR R3 R0 K36 0x780E0002, // 0072 JMPF R3 #0076 0x880C0121, // 0073 GETMBR R3 R0 K33 - 0x300C0719, // 0074 OR R3 R3 K25 + 0x300C071A, // 0074 OR R3 R3 K26 0x90024203, // 0075 SETMBR R0 K33 R3 0x880C0125, // 0076 GETMBR R3 R0 K37 0x780E0002, // 0077 JMPF R3 #007B @@ -387,11 +387,11 @@ be_local_closure(class_Matter_Frame_encode_frame, /* name */ 0x2C140A06, // 008A AND R5 R5 R6 0x70020000, // 008B JMP #008D 0x58140012, // 008C LDCONST R5 K18 - 0x58180019, // 008D LDCONST R6 K25 + 0x5818001A, // 008D LDCONST R6 K26 0x7C0C0600, // 008E CALL R3 3 0x8C0C0509, // 008F GETMET R3 R2 K9 0x88140128, // 0090 GETMBR R5 R0 K40 - 0x58180019, // 0091 LDCONST R6 K25 + 0x5818001A, // 0091 LDCONST R6 K26 0x7C0C0600, // 0092 CALL R3 3 0x880C0124, // 0093 GETMBR R3 R0 K36 0x780E0003, // 0094 JMPF R3 #0099 @@ -436,8 +436,8 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x58140012, // 0003 LDCONST R5 K18 0x5818000B, // 0004 LDCONST R6 K11 0x7C0C0600, // 0005 CALL R3 3 - 0x90021403, // 0006 SETMBR R0 K10 R3 - 0x880C010A, // 0007 GETMBR R3 R0 K10 + 0x90022A03, // 0006 SETMBR R0 K21 R3 + 0x880C0115, // 0007 GETMBR R3 R0 K21 0x541200F7, // 0008 LDINT R4 248 0x2C0C0604, // 0009 AND R3 R3 R4 0x200C0712, // 000A NE R3 R3 K18 @@ -445,28 +445,28 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x500C0000, // 000C LDBOOL R3 0 0 0x80040600, // 000D RET 1 R3 0x8C0C052C, // 000E GETMET R3 R2 K44 - 0x58140019, // 000F LDCONST R5 K25 + 0x5814001A, // 000F LDCONST R5 K26 0x5818000B, // 0010 LDCONST R6 K11 0x7C0C0600, // 0011 CALL R3 3 - 0x90022A03, // 0012 SETMBR R0 K21 R3 + 0x90022C03, // 0012 SETMBR R0 K22 R3 0x8C0C052C, // 0013 GETMET R3 R2 K44 0x58140012, // 0014 LDCONST R5 K18 - 0x58180019, // 0015 LDCONST R6 K25 + 0x5818001A, // 0015 LDCONST R6 K26 0x7C0C0600, // 0016 CALL R3 3 - 0x90022C03, // 0017 SETMBR R0 K22 R3 - 0x880C0116, // 0018 GETMBR R3 R0 K22 - 0x1C0C0717, // 0019 EQ R3 R3 K23 + 0x90022E03, // 0017 SETMBR R0 K23 R3 + 0x880C0117, // 0018 GETMBR R3 R0 K23 + 0x1C0C0718, // 0019 EQ R3 R3 K24 0x780E0001, // 001A JMPF R3 #001D 0x500C0000, // 001B LDBOOL R3 0 0 0x80040600, // 001C RET 1 R3 0x8C0C052B, // 001D GETMET R3 R2 K43 - 0x58140017, // 001E LDCONST R5 K23 + 0x58140018, // 001E LDCONST R5 K24 0x5818000B, // 001F LDCONST R6 K11 0x7C0C0600, // 0020 CALL R3 3 - 0x90023403, // 0021 SETMBR R0 K26 R3 + 0x90021403, // 0021 SETMBR R0 K10 R3 0x8C0C052C, // 0022 GETMET R3 R2 K44 0x54160007, // 0023 LDINT R5 8 - 0x08162E05, // 0024 MUL R5 K23 R5 + 0x08163005, // 0024 MUL R5 K24 R5 0x541A0006, // 0025 LDINT R6 7 0x00140A06, // 0026 ADD R5 R5 R6 0x5818000B, // 0027 LDCONST R6 K11 @@ -474,7 +474,7 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x90023603, // 0029 SETMBR R0 K27 R3 0x8C0C052C, // 002A GETMET R3 R2 K44 0x54160007, // 002B LDINT R5 8 - 0x08162E05, // 002C MUL R5 K23 R5 + 0x08163005, // 002C MUL R5 K24 R5 0x541A0005, // 002D LDINT R6 6 0x00140A06, // 002E ADD R5 R5 R6 0x5818000B, // 002F LDCONST R6 K11 @@ -482,7 +482,7 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x90023803, // 0031 SETMBR R0 K28 R3 0x8C0C052C, // 0032 GETMET R3 R2 K44 0x54160007, // 0033 LDINT R5 8 - 0x08162E05, // 0034 MUL R5 K23 R5 + 0x08163005, // 0034 MUL R5 K24 R5 0x541A0004, // 0035 LDINT R6 5 0x00140A06, // 0036 ADD R5 R5 R6 0x5818000B, // 0037 LDCONST R6 K11 @@ -490,8 +490,8 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x90025A03, // 0039 SETMBR R0 K45 R3 0x8C0C052C, // 003A GETMET R3 R2 K44 0x54160007, // 003B LDINT R5 8 - 0x08162E05, // 003C MUL R5 K23 R5 - 0x58180019, // 003D LDCONST R6 K25 + 0x08163005, // 003C MUL R5 K24 R5 + 0x5818001A, // 003D LDCONST R6 K26 0x7C0C0600, // 003E CALL R3 3 0x90023A03, // 003F SETMBR R0 K29 R3 0x880C011D, // 0040 GETMBR R3 R0 K29 @@ -501,9 +501,9 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x80040600, // 0044 RET 1 R3 0x8C0C052B, // 0045 GETMET R3 R2 K43 0x5814000B, // 0046 LDCONST R5 K11 - 0x58180019, // 0047 LDCONST R6 K25 + 0x5818001A, // 0047 LDCONST R6 K26 0x7C0C0600, // 0048 CALL R3 3 - 0x90023003, // 0049 SETMBR R0 K24 R3 + 0x90023203, // 0049 SETMBR R0 K25 R3 0x8C0C052B, // 004A GETMET R3 R2 K43 0x54160003, // 004B LDINT R5 4 0x541A0003, // 004C LDINT R6 4 @@ -511,7 +511,7 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x90021803, // 004E SETMBR R0 K12 R3 0x540E0007, // 004F LDINT R3 8 0x00040203, // 0050 ADD R1 R1 R3 - 0x880C0115, // 0051 GETMBR R3 R0 K21 + 0x880C0116, // 0051 GETMBR R3 R0 K22 0x780E0006, // 0052 JMPF R3 #005A 0x540E0006, // 0053 LDINT R3 7 0x000C0203, // 0054 ADD R3 R1 R3 @@ -520,7 +520,7 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x90023C03, // 0057 SETMBR R0 K30 R3 0x540E0007, // 0058 LDINT R3 8 0x00040203, // 0059 ADD R1 R1 R3 - 0x880C0116, // 005A GETMBR R3 R0 K22 + 0x880C0117, // 005A GETMBR R3 R0 K23 0x1C0C070B, // 005B EQ R3 R3 K11 0x780E0007, // 005C JMPF R3 #0065 0x540E0006, // 005D LDINT R3 7 @@ -531,22 +531,22 @@ be_local_closure(class_Matter_Frame_decode_header, /* name */ 0x540E0007, // 0062 LDINT R3 8 0x00040203, // 0063 ADD R1 R1 R3 0x70020008, // 0064 JMP #006E - 0x880C0116, // 0065 GETMBR R3 R0 K22 - 0x1C0C0719, // 0066 EQ R3 R3 K25 + 0x880C0117, // 0065 GETMBR R3 R0 K23 + 0x1C0C071A, // 0066 EQ R3 R3 K26 0x780E0005, // 0067 JMPF R3 #006E 0x8C0C052B, // 0068 GETMET R3 R2 K43 0x5C140200, // 0069 MOVE R5 R1 - 0x58180019, // 006A LDCONST R6 K25 + 0x5818001A, // 006A LDCONST R6 K26 0x7C0C0600, // 006B CALL R3 3 0x90024003, // 006C SETMBR R0 K32 R3 - 0x00040319, // 006D ADD R1 R1 K25 + 0x0004031A, // 006D ADD R1 R1 K26 0x880C012D, // 006E GETMBR R3 R0 K45 0x780E0005, // 006F JMPF R3 #0076 0x8C0C052B, // 0070 GETMET R3 R2 K43 0x5C140200, // 0071 MOVE R5 R1 - 0x58180019, // 0072 LDCONST R6 K25 + 0x5818001A, // 0072 LDCONST R6 K26 0x7C0C0600, // 0073 CALL R3 3 - 0x00100719, // 0074 ADD R4 R3 K25 + 0x0010071A, // 0074 ADD R4 R3 K26 0x00040204, // 0075 ADD R1 R1 R4 0x90020801, // 0076 SETMBR R0 K4 R1 0x500C0200, // 0077 LDBOOL R3 1 0 @@ -620,16 +620,16 @@ be_local_closure(class_Matter_Frame_build_response, /* name */ 0x900E2604, // 000A SETMBR R3 K19 R4 0x88100114, // 000B GETMBR R4 R0 K20 0x900E2804, // 000C SETMBR R3 K20 R4 - 0x88100115, // 000D GETMBR R4 R0 K21 + 0x88100116, // 000D GETMBR R4 R0 K22 0x78120003, // 000E JMPF R4 #0013 - 0x900E2D0B, // 000F SETMBR R3 K22 K11 + 0x900E2F0B, // 000F SETMBR R3 K23 K11 0x8810011E, // 0010 GETMBR R4 R0 K30 0x900E3E04, // 0011 SETMBR R3 K31 R4 0x70020000, // 0012 JMP #0014 - 0x900E2D12, // 0013 SETMBR R3 K22 K18 + 0x900E2F12, // 0013 SETMBR R3 K23 K18 0x88100100, // 0014 GETMBR R4 R0 K0 0x900E0004, // 0015 SETMBR R3 K0 R4 - 0x88100118, // 0016 GETMBR R4 R0 K24 + 0x88100119, // 0016 GETMBR R4 R0 K25 0x20100912, // 0017 NE R4 R4 K18 0x7812000D, // 0018 JMPF R4 #0027 0x88100100, // 0019 GETMBR R4 R0 K0 @@ -644,14 +644,14 @@ be_local_closure(class_Matter_Frame_build_response, /* name */ 0x900E1804, // 0022 SETMBR R3 K12 R4 0x88100100, // 0023 GETMBR R4 R0 K0 0x88100932, // 0024 GETMBR R4 R4 K50 - 0x900E3004, // 0025 SETMBR R3 K24 R4 + 0x900E3204, // 0025 SETMBR R3 K25 R4 0x70020005, // 0026 JMP #002D 0x88100100, // 0027 GETMBR R4 R0 K0 0x88100934, // 0028 GETMBR R4 R4 K52 0x8C100935, // 0029 GETMET R4 R4 K53 0x7C100200, // 002A CALL R4 1 0x900E1804, // 002B SETMBR R3 K12 R4 - 0x900E3112, // 002C SETMBR R3 K24 K18 + 0x900E3312, // 002C SETMBR R3 K25 K18 0x88100125, // 002D GETMBR R4 R0 K37 0x78120001, // 002E JMPF R4 #0031 0x58100012, // 002F LDCONST R4 K18 @@ -673,7 +673,7 @@ be_local_closure(class_Matter_Frame_build_response, /* name */ 0x70020000, // 003F JMP #0041 0x58100012, // 0040 LDCONST R4 K18 0x900E4604, // 0041 SETMBR R3 K35 R4 - 0x88100718, // 0042 GETMBR R4 R3 K24 + 0x88100719, // 0042 GETMBR R4 R3 K25 0x1C100912, // 0043 EQ R4 R4 K18 0x78120013, // 0044 JMPF R4 #0059 0xB8125C00, // 0045 GETNGBL R4 K46 @@ -691,10 +691,10 @@ be_local_closure(class_Matter_Frame_build_response, /* name */ 0x60180018, // 0051 GETGBL R6 G24 0x581C0039, // 0052 LDCONST R7 K57 0x88200700, // 0053 GETMBR R8 R3 K0 - 0x88201118, // 0054 GETMBR R8 R8 K24 + 0x88201119, // 0054 GETMBR R8 R8 K25 0x5C240800, // 0055 MOVE R9 R4 0x7C180600, // 0056 CALL R6 3 - 0x581C0017, // 0057 LDCONST R7 K23 + 0x581C0018, // 0057 LDCONST R7 K24 0x7C140400, // 0058 CALL R5 2 0x80040600, // 0059 RET 1 R3 }) @@ -731,7 +731,7 @@ be_local_closure(class_Matter_Frame_decrypt, /* name */ 0x781E002B, // 0008 JMPF R7 #0035 0xB81E7000, // 0009 GETNGBL R7 K56 0x5820003B, // 000A LDCONST R8 K59 - 0x58240019, // 000B LDCONST R9 K25 + 0x5824001A, // 000B LDCONST R9 K26 0x7C1C0400, // 000C CALL R7 2 0x8C1C053C, // 000D GETMET R7 R2 K60 0x7C1C0200, // 000E CALL R7 1 @@ -741,7 +741,7 @@ be_local_closure(class_Matter_Frame_decrypt, /* name */ 0x60240015, // 0012 GETGBL R9 G21 0x7C240000, // 0013 CALL R9 0 0x8C241309, // 0014 GETMET R9 R9 K9 - 0x882C0118, // 0015 GETMBR R11 R0 K24 + 0x882C0119, // 0015 GETMBR R11 R0 K25 0x5431FFFD, // 0016 LDINT R12 -2 0x7C240600, // 0017 CALL R9 3 0x542A0004, // 0018 LDINT R10 5 @@ -761,10 +761,10 @@ be_local_closure(class_Matter_Frame_decrypt, /* name */ 0x8C30193F, // 0026 GETMET R12 R12 K63 0x5C381400, // 0027 MOVE R14 R10 0x5C3C1200, // 0028 MOVE R15 R9 - 0x58400019, // 0029 LDCONST R16 K25 + 0x5840001A, // 0029 LDCONST R16 K26 0x7C300800, // 002A CALL R12 4 0x5C2C1800, // 002B MOVE R11 R12 - 0x40322517, // 002C CONNECT R12 K18 K23 + 0x40322518, // 002C CONNECT R12 K18 K24 0x88340103, // 002D GETMBR R13 R0 K3 0x94301A0C, // 002E GETIDX R12 R13 R12 0x0030180B, // 002F ADD R12 R12 R11 @@ -832,7 +832,7 @@ be_local_closure(class_Matter_Frame_decrypt, /* name */ 0x70020003, // 006D JMP #0072 0xB8267000, // 006E GETNGBL R9 K56 0x58280042, // 006F LDCONST R10 K66 - 0x582C0017, // 0070 LDCONST R11 K23 + 0x582C0018, // 0070 LDCONST R11 K24 0x7C240400, // 0071 CALL R9 2 0x80041000, // 0072 RET 1 R8 }) @@ -867,13 +867,13 @@ be_local_closure(class_Matter_Frame_build_standalone_ack, /* name */ 0x900A2603, // 0006 SETMBR R2 K19 R3 0x880C0114, // 0007 GETMBR R3 R0 K20 0x900A2803, // 0008 SETMBR R2 K20 R3 - 0x880C0115, // 0009 GETMBR R3 R0 K21 + 0x880C0116, // 0009 GETMBR R3 R0 K22 0x780E0003, // 000A JMPF R3 #000F - 0x900A2D0B, // 000B SETMBR R2 K22 K11 + 0x900A2F0B, // 000B SETMBR R2 K23 K11 0x880C011E, // 000C GETMBR R3 R0 K30 0x900A3E03, // 000D SETMBR R2 K31 R3 0x70020000, // 000E JMP #0010 - 0x900A2D12, // 000F SETMBR R2 K22 K18 + 0x900A2F12, // 000F SETMBR R2 K23 K18 0x880C0100, // 0010 GETMBR R3 R0 K0 0x900A0003, // 0011 SETMBR R2 K0 R3 0x880C0100, // 0012 GETMBR R3 R0 K0 @@ -882,7 +882,7 @@ be_local_closure(class_Matter_Frame_build_standalone_ack, /* name */ 0x900A1803, // 0015 SETMBR R2 K12 R3 0x880C0100, // 0016 GETMBR R3 R0 K0 0x880C0732, // 0017 GETMBR R3 R3 K50 - 0x900A3003, // 0018 SETMBR R2 K24 R3 + 0x900A3203, // 0018 SETMBR R2 K25 R3 0x880C0125, // 0019 GETMBR R3 R0 K37 0x780E0001, // 001A JMPF R3 #001D 0x580C0012, // 001B LDCONST R3 K18 @@ -939,7 +939,7 @@ be_local_closure(class_Matter_Frame_initiate_response, /* name */ 0x90122606, // 000A SETMBR R4 K19 R6 0x88180345, // 000B GETMBR R6 R1 K69 0x90122806, // 000C SETMBR R4 K20 R6 - 0x90122D12, // 000D SETMBR R4 K22 K18 + 0x90122F12, // 000D SETMBR R4 K23 K18 0x90120001, // 000E SETMBR R4 K0 R1 0x78060008, // 000F JMPF R1 #0019 0x88180332, // 0010 GETMBR R6 R1 K50 @@ -949,13 +949,13 @@ be_local_closure(class_Matter_Frame_initiate_response, /* name */ 0x7C180200, // 0014 CALL R6 1 0x90121806, // 0015 SETMBR R4 K12 R6 0x88180332, // 0016 GETMBR R6 R1 K50 - 0x90123006, // 0017 SETMBR R4 K24 R6 + 0x90123206, // 0017 SETMBR R4 K25 R6 0x70020004, // 0018 JMP #001E 0x88180334, // 0019 GETMBR R6 R1 K52 0x8C180D35, // 001A GETMET R6 R6 K53 0x7C180200, // 001B CALL R6 1 0x90121806, // 001C SETMBR R4 K12 R6 - 0x90123112, // 001D SETMBR R4 K24 K18 + 0x90123312, // 001D SETMBR R4 K25 K18 0x90124B0B, // 001E SETMBR R4 K37 K11 0x90124C02, // 001F SETMBR R4 K38 R2 0x88180346, // 0020 GETMBR R6 R1 K70 @@ -1013,14 +1013,14 @@ be_local_closure(class_Matter_Frame_decode_payload, /* name */ 0x8C0C052C, // 000F GETMET R3 R2 K44 0x54160007, // 0010 LDINT R5 8 0x08140205, // 0011 MUL R5 R1 R5 - 0x00140B17, // 0012 ADD R5 R5 K23 + 0x00140B18, // 0012 ADD R5 R5 K24 0x5818000B, // 0013 LDCONST R6 K11 0x7C0C0600, // 0014 CALL R3 3 0x90028E03, // 0015 SETMBR R0 K71 R3 0x8C0C052C, // 0016 GETMET R3 R2 K44 0x54160007, // 0017 LDINT R5 8 0x08140205, // 0018 MUL R5 R1 R5 - 0x00140B19, // 0019 ADD R5 R5 K25 + 0x00140B1A, // 0019 ADD R5 R5 K26 0x5818000B, // 001A LDCONST R6 K11 0x7C0C0600, // 001B CALL R3 3 0x90024603, // 001C SETMBR R0 K35 R3 @@ -1043,8 +1043,8 @@ be_local_closure(class_Matter_Frame_decode_payload, /* name */ 0x7C0C0600, // 002D CALL R3 3 0x90024C03, // 002E SETMBR R0 K38 R3 0x8C0C052B, // 002F GETMET R3 R2 K43 - 0x00140319, // 0030 ADD R5 R1 K25 - 0x58180019, // 0031 LDCONST R6 K25 + 0x0014031A, // 0030 ADD R5 R1 K26 + 0x5818001A, // 0031 LDCONST R6 K26 0x7C0C0600, // 0032 CALL R3 3 0x90024E03, // 0033 SETMBR R0 K39 R3 0x880C0125, // 0034 GETMBR R3 R0 K37 @@ -1056,7 +1056,7 @@ be_local_closure(class_Matter_Frame_decode_payload, /* name */ 0x8C0C052B, // 003A GETMET R3 R2 K43 0x54160003, // 003B LDINT R5 4 0x00140205, // 003C ADD R5 R1 R5 - 0x58180019, // 003D LDCONST R6 K25 + 0x5818001A, // 003D LDCONST R6 K26 0x7C0C0600, // 003E CALL R3 3 0x90025003, // 003F SETMBR R0 K40 R3 0x540E0005, // 0040 LDINT R3 6 @@ -1065,10 +1065,10 @@ be_local_closure(class_Matter_Frame_decode_payload, /* name */ 0x780E0005, // 0043 JMPF R3 #004A 0x8C0C052B, // 0044 GETMET R3 R2 K43 0x5C140200, // 0045 MOVE R5 R1 - 0x58180019, // 0046 LDCONST R6 K25 + 0x5818001A, // 0046 LDCONST R6 K26 0x7C0C0600, // 0047 CALL R3 3 0x90029003, // 0048 SETMBR R0 K72 R3 - 0x00040319, // 0049 ADD R1 R1 K25 + 0x0004031A, // 0049 ADD R1 R1 K26 0x880C0124, // 004A GETMBR R3 R0 K36 0x780E0006, // 004B JMPF R3 #0053 0x8C0C052B, // 004C GETMET R3 R2 K43 @@ -1082,9 +1082,9 @@ be_local_closure(class_Matter_Frame_decode_payload, /* name */ 0x780E0005, // 0054 JMPF R3 #005B 0x8C0C052B, // 0055 GETMET R3 R2 K43 0x5C140200, // 0056 MOVE R5 R1 - 0x58180019, // 0057 LDCONST R6 K25 + 0x5818001A, // 0057 LDCONST R6 K26 0x7C0C0600, // 0058 CALL R3 3 - 0x00100719, // 0059 ADD R4 R3 K25 + 0x0010071A, // 0059 ADD R4 R3 K26 0x00040204, // 005A ADD R1 R1 R4 0x90025401, // 005B SETMBR R0 K42 R1 0x80040000, // 005C RET 1 R0 From 0fb39b9bac369c62f0129868090653d245728813 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:40:59 +0100 Subject: [PATCH 120/205] Update changelogs --- CHANGELOG.md | 2 +- RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f358a9d2..e544314cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file. ### Changed ### Fixed -- Matter provisioning with matter.js controller +- Matter provisioning with matter.js controller (#22470) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 32d0255da..094ea970d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -168,5 +168,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - ESP32 Arduino Core IPv6 zones used by Matter [#22378](https://github.com/arendst/Tasmota/issues/22378) - ESP32, ESP32-S2 and ESP32-S3 re-enable touch buttons [#22446](https://github.com/arendst/Tasmota/issues/22446) - ESP32-S3 UART output mode for Tx [#22426](https://github.com/arendst/Tasmota/issues/22426) +- Matter provisioning with matter.js controller [#22470](https://github.com/arendst/Tasmota/issues/22470) ### Removed From 88810fc92caa8f749358eb21560e9e58ceb245ec Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:57:41 +0100 Subject: [PATCH 121/205] Increase OTA delays to allow GUI console updates --- tasmota/tasmota_support/support_tasmota.ino | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino index f05f1b724..90a171787 100644 --- a/tasmota/tasmota_support/support_tasmota.ino +++ b/tasmota/tasmota_support/support_tasmota.ino @@ -1489,12 +1489,11 @@ void Every250mSeconds(void) Response_P(PSTR("{\"" D_CMND_UPGRADE "\":\"")); if (ota_result) { ResponseAppend_P(PSTR(D_JSON_SUCCESSFUL ". " D_JSON_RESTARTING)); - TasmotaGlobal.restart_flag = 2; + TasmotaGlobal.restart_flag = 5; // Allow time for webserver to update console } else { ResponseAppend_P(PSTR(D_JSON_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str()); } ResponseAppend_P(PSTR("\"}")); -// TasmotaGlobal.restart_flag = 2; // Restart anyway to keep memory clean webserver MqttPublishPrefixTopicRulesProcess_P(STAT, PSTR(D_CMND_UPGRADE)); AllowInterrupts(1); } @@ -1624,7 +1623,7 @@ void Every250mSeconds(void) if (1 == RtcSettings.ota_loader) { RtcSettings.ota_loader = 0; AddLog(LOG_LEVEL_DEBUG, PSTR("OTA: Propagating upload")); - TasmotaGlobal.ota_state_flag = 3; + TasmotaGlobal.ota_state_flag = 6; // Allow time for webserver to update console } #endif // FIRMWARE_MINIMAL From 50b6f74295e6361c55e21febab23190e7d84ce5a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 12 Nov 2024 21:49:36 +0100 Subject: [PATCH 122/205] Better check for existing Ethernet support in Arduino libs (#22473) * use IDF var for eth check --- tasmota/include/tasmota_configurations_ESP32.h | 8 +++++--- tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 9eb52a7b5..e4d714325 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -189,10 +189,12 @@ #undef USE_ESP32_WDT // disable watchdog on SAFEBOOT until more testing is done #if CONFIG_FREERTOS_UNICORE || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_ETH_ENABLED // Check for Ethernet support in Arduino libs // #undef USE_MQTT_TLS // #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge console Tee (+4.5k code) #define USE_SPI // Make SPI Ethernet adapters useable (+124 bytes) #define USE_ETHERNET +#endif // CONFIG_ETH_ENABLED #endif // CONFIG_FREERTOS_UNICORE || CONFIG_IDF_TARGET_ESP32S3 #endif // FIRMWARE_SAFEBOOT @@ -830,15 +832,15 @@ #endif // USE_MATTER_DEVICE /*********************************************************************************************\ - * Post-process compile options for esp32-c2 + * Post-process for switched off Ethernet support in Arduino static libs \*********************************************************************************************/ -#ifdef CONFIG_IDF_TARGET_ESP32C2 +#ifndef CONFIG_ETH_ENABLED #undef USE_ETHERNET #ifdef FIRMWARE_MINIMAL #undef USE_SPI #endif // FIRMWARE_MINIMAL -#endif // CONFIG_IDF_TARGET_ESP32C2 +#endif // CONFIG_ETH_ENABLED #endif // ESP32 #endif // _TASMOTA_CONFIGURATIONS_ESP32_H_ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index 6a40129ef..5fb4712c5 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -18,7 +18,8 @@ */ #ifdef ESP32 -#ifndef CONFIG_IDF_TARGET_ESP32C2 +#include "sdkconfig.h" +#ifdef CONFIG_ETH_ENABLED #ifdef USE_ETHERNET /*********************************************************************************************\ * Ethernet support for ESP32 From 551c919ae20dad91ddcd3d9ec02f5539b6aba384 Mon Sep 17 00:00:00 2001 From: vtHydroponics <132159689+vtHydroponics@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:23:45 -0500 Subject: [PATCH 123/205] MS5837 pressure offset persistent between resets (#22476) * Finalized gain/integration adjustment trees * Fixed the bugs * works but polishing code * need to debug pressure in bmp * updated temp to change via setoption8 command from tasmota * sensor table working, value reporting working, need to update dependency on sensor duality * working * updated file name for ms5837 xsns file * final working with renamed for current updates (128->116) * resolved PR comments for extra spaces, xi2c_96 * removed extra spaces, added unit for inches across languages * removed inches as a unit from language files * pressure offset retained between resets --- tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino b/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino index 403b1c3f9..b67f4a38a 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_116_ms5837.ino @@ -52,6 +52,9 @@ void MS5837init(void) { ms5837_sensor.setModel(ms5837_sensor.MS5837_02BA); ms5837_sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater) ms5837_start = true; + if(!isnan(Settings->ms5837_pressure_offset)) { + ms5837_pressure_offset = Settings->ms5837_pressure_offset; + } I2cSetActiveFound(MS5837_ADDR, "MS5837"); } } @@ -124,10 +127,12 @@ bool ms5837CommandSensor() { #ifdef USE_BMP ms5837_pressure_offset = bmp_sensors[0].bmp_pressure - ms5837_sensor.pressure(); #endif // USE_BMP + Settings->ms5837_pressure_offset = ms5837_pressure_offset; Response_P(PSTR("Set MS5837 pressure offset to %f"),ms5837_pressure_offset); break; case 1: ms5837_pressure_offset = value; + Settings->ms5837_pressure_offset = ms5837_pressure_offset; Response_P(PSTR("Set MS5837 pressure offset to %f"),ms5837_pressure_offset); break; } From b195bcd88d7c720143769ee51c00256b22ac7660 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 13 Nov 2024 22:38:22 +0100 Subject: [PATCH 124/205] use sdkconfig define `CONFIG_ETH_ENABLED` to check Ethernet availability (#22481) --- lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h b/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h index 8e55a735d..a891eb1bf 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h @@ -75,7 +75,7 @@ #if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) -#if defined(ESP32) && __has_include() +#if defined(ESP32) && defined(CONFIG_ETH_ENABLED) #include #define ESP_MAIL_ETH_IS_AVAILABLE #elif defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) @@ -128,4 +128,4 @@ #define WiFI_CONNECTED false #endif -#endif \ No newline at end of file +#endif From dd99642cf78c0d5adcd2c29305d7dabb7e51be2d Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:24:20 +0100 Subject: [PATCH 125/205] Prevent crashing when `display.ini` is missing end `#` (#22471) --- CHANGELOG.md | 1 + lib/lib_display/UDisplay/uDisplay.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e544314cc..b6bcfcdea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Matter provisioning with matter.js controller (#22470) +- Prevent crashing when `display.ini` is missing end `#` ### Removed diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp index 4af702125..96b59e3dd 100755 --- a/lib/lib_display/UDisplay/uDisplay.cpp +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -680,14 +680,15 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { if (*lp == '\n' || *lp == ' ') { // Add space char lp++; } else { - lp = strchr(lp, '\n'); - if (!lp) { - lp = strchr(lp, ' '); - if (!lp) { + char *lp1; + lp1 = strchr(lp, '\n'); + if (!lp1) { + lp1 = strchr(lp, ' '); + if (!lp1) { break; } } - lp++; + lp = lp1 + 1; } } From 0dcfa74ef3abace6093954c764100d7329beb32e Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Thu, 14 Nov 2024 09:51:30 +0100 Subject: [PATCH 126/205] Update pl_PL.h (#22483) --- tasmota/language/pl_PL.h | 128 +++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 94e6f1ab1..7d2cc19b4 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -51,15 +51,15 @@ #define D_DECIMAL_SEPARATOR "," // Common -#define D_ABSOLUTE_HUMIDITY "Abs Humidity" +#define D_ABSOLUTE_HUMIDITY "Wilgotność" #define D_ADMIN "Admin" #define D_AIR_QUALITY "Jakość powietrza" #define D_AP "AP" // Access Point #define D_AS "jak" #define D_AUTO "AUTO" -#define D_BATTERY "Battery" -#define D_BATT "Batt" // Short for Battery -#define D_BATTERY_CHARGE "Charge" // Battery charge in % +#define D_BATTERY "Bateria" +#define D_BATT "Bat" // Short for Battery +#define D_BATTERY_CHARGE "Ładowanie" // Battery charge in % #define D_BLINK "Miganie" #define D_BLINKOFF "Miganie - Wył." #define D_BOOT_COUNT "Licznik restartów" @@ -76,13 +76,13 @@ #define D_COMMAND "Komenda" #define D_CONNECTED "Połączony" #define D_CORS_DOMAIN "Domena CORS" -#define D_COLOR "Color" +#define D_COLOR "Kolor" #define D_COUNT "Licz" #define D_COUNTER "Licznik" #define D_CT_POWER "Moc CT" #define D_CURRENT "Prąd" // As in Voltage and Current -#define D_CURRENT_NEUTRAL "Current Neutral" -#define D_DATA "Data" +#define D_CURRENT_NEUTRAL "Prąd N" +#define D_DATA "Dane" #define D_DARKLIGHT "Ciemny" #define D_DEBUG "Debug" #define D_DEWPOINT "Punkt rosy" @@ -107,7 +107,7 @@ #define D_FILE_SYSTEM_SIZE "Rozmiar systemu plików" #define D_FLOW_RATE "Przepływ" #define D_FRAGMENTATION "frag." // Lower case abbreviated version of fragmentation used in "memory fragmentation" -#define D_FRAME_RATE "Frame rate" +#define D_FRAME_RATE "Liczba klatek" #define D_FREE_MEMORY "Wolna pamięć" #define D_PSR_MAX_MEMORY "Pamięć PS-RAM" #define D_PSR_FREE_MEMORY "Wolna pamięć PS-RAM" @@ -116,8 +116,8 @@ #define D_GATEWAY "Brama" #define D_GROUP "Grupa" #define D_HOST "Serwer" -#define D_HALL_EFFECT "Hall Effect" -#define D_HEATINDEX "Heat index" +#define D_HALL_EFFECT "Efekt Hall" +#define D_HEATINDEX "Indeks ciepła" #define D_HOSTNAME "Nazwa serwera" #define D_HUMIDITY "Wilgotność" #define D_ILLUMINANCE "Podświetlanie" @@ -152,7 +152,7 @@ #define D_POWER_FACTOR "Cosinus fi" #define D_POWERUSAGE "Moc" #define D_POWERUSAGE_ACTIVE "Moc czynna" -#define D_POWERUSAGE_ACTIVE_TOTAL "Active Power Total" +#define D_POWERUSAGE_ACTIVE_TOTAL "Moc czynna całkowita" #define D_POWERUSAGE_APPARENT "Moc pozorna" #define D_POWERUSAGE_REACTIVE "Moc bierna" #define D_PRESSURE "Ciśnienie" @@ -188,9 +188,9 @@ #define D_TRANSMIT "Wyślij" #define D_TRUE "Prawda" #define D_TVOC "TVOC" -#define D_TWILIGHT_ASTRONOMICAL "Astronomical" -#define D_TWILIGHT_CIVIL "Civil" -#define D_TWILIGHT_NAUTICAL "Nautical" +#define D_TWILIGHT_ASTRONOMICAL "Astronomiczny" +#define D_TWILIGHT_CIVIL "Cywilny" +#define D_TWILIGHT_NAUTICAL "Morski" #define D_UPLOAD "Wgraj" #define D_UPTIME "Czas pracy" #define D_USED "użyte" @@ -201,8 +201,8 @@ #define D_UV_INDEX_2 "Średni" #define D_UV_INDEX_3 "Wysoki" #define D_UV_INDEX_4 "Niebezpieczny" -#define D_UV_INDEX_5 "Burn L1/2" -#define D_UV_INDEX_6 "Burn L3" +#define D_UV_INDEX_5 "Krytyczny L1/2" +#define D_UV_INDEX_6 "Krytyczny L3" #define D_UV_INDEX_7 "OoR" #define D_UV_LEVEL "Poziom UV" #define D_UV_POWER "Moc UV" @@ -275,8 +275,8 @@ #define D_CONFIGURATION "Konfiguracja" #define D_INFORMATION "Informacje" #define D_FIRMWARE_UPGRADE "Aktualizacja oprogramowania" -#define D_MANAGEMENT "Konsole" -#define D_GPIO_VIEWER "GPIO Viewer" +#define D_MANAGEMENT "Narzędzia" +#define D_GPIO_VIEWER "Wizualizacja GPIO" #define D_CONSOLE "Konsola" #define D_CONFIRM_RESTART "Potwierdź restart" @@ -528,7 +528,7 @@ // xdrv_89_dali.ino #define D_SENSOR_DALI_RX "Dali RX" #define D_SENSOR_DALI_TX "Dali TX" -#define D_CONFIGURE_DALI "Config DALI" +#define D_CONFIGURE_DALI "Konfiguracja DALI" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia dzisiaj" @@ -537,8 +537,8 @@ // xsns_100_ina3221.ino #define D_UNIT_CHARGE "Ah" -#define D_CHARGE "Charge" -#define D_ENERGY "Energy" +#define D_CHARGE "Ładowanie" +#define D_ENERGY "Energia" // xdrv_27_shutter.ino #define D_OPEN "Otwórz" @@ -571,12 +571,12 @@ #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" // xdrv_79_esp32_ble.ino -#define D_CONFIGURE_BLE "Configure BLE" -#define D_BLE_PARAMETERS "Bluetooth Settings" -#define D_MQTT_BLE_ENABLE "Enable Bluetooth" -#define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" -#define D_BLE_DEVICES "Devices Seen" -#define D_BLE_REMARK "items marked (*) are not stored in config" +#define D_CONFIGURE_BLE "Konfiguracja BLE" +#define D_BLE_PARAMETERS "Ustawienia Bluetooth" +#define D_MQTT_BLE_ENABLE "Załącz Bluetooth" +#define D_MQTT_BLE_ACTIVESCAN "Załącz Aktywne Skanowanie(*)" +#define D_BLE_DEVICES "Znalezione Urządzenia" +#define D_BLE_REMARK "rzeczy oznaczone (*) nie są zapisywane w konfiguracji" // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "Czujnik zajęty" @@ -1227,52 +1227,52 @@ #define D_NEOPOOL_MACH_GENERIC "Generic" #define D_NEOPOOL_MACH_BAYROL "Bayrol" #define D_NEOPOOL_MACH_HAY "Hay" -#define D_NEOPOOL_FILTRATION_MANUAL "Manual" // Filtration modes +#define D_NEOPOOL_FILTRATION_MANUAL "Ręczny" // Filtration modes #define D_NEOPOOL_FILTRATION_AUTO "Auto" -#define D_NEOPOOL_FILTRATION_HEATING "Heating" +#define D_NEOPOOL_FILTRATION_HEATING "Ogrzewanie" #define D_NEOPOOL_FILTRATION_SMART "Smart" #define D_NEOPOOL_FILTRATION_INTELLIGENT "Intelligent" #define D_NEOPOOL_FILTRATION_BACKWASH "Backwash" #define D_NEOPOOL_FILTRATION_NONE "" // Filtration speed level -#define D_NEOPOOL_FILTRATION_SLOW "slow" -#define D_NEOPOOL_FILTRATION_MEDIUM "medium" -#define D_NEOPOOL_FILTRATION_FAST "fast" -#define D_NEOPOOL_TYPE "Type" // Sensor & relais names +#define D_NEOPOOL_FILTRATION_SLOW "wolny" +#define D_NEOPOOL_FILTRATION_MEDIUM "średni" +#define D_NEOPOOL_FILTRATION_FAST "szybki" +#define D_NEOPOOL_TYPE "Typ" // Sensor & relais names #define D_NEOPOOL_REDOX "Redox" #define D_NEOPOOL_CHLORINE "Chlorine" #define D_NEOPOOL_CONDUCTIVITY "Conductivity" #define D_NEOPOOL_IONIZATION "Ionization" #define D_NEOPOOL_HYDROLYSIS "Hydrolysis" -#define D_NEOPOOL_RELAY "Relay" -#define D_NEOPOOL_RELAY_FILTRATION "Filtration" // Relay assignment -#define D_NEOPOOL_RELAY_LIGHT "Light" -#define D_NEOPOOL_RELAY_PH_ACID "Acid pump" -#define D_NEOPOOL_RELAY_PH_BASE "Base pump" -#define D_NEOPOOL_RELAY_RX "Redox level" -#define D_NEOPOOL_RELAY_CL "Chlorine pump" +#define D_NEOPOOL_RELAY "Przekaźnik" +#define D_NEOPOOL_RELAY_FILTRATION "Filtrowanie" // Relay assignment +#define D_NEOPOOL_RELAY_LIGHT "Światło" +#define D_NEOPOOL_RELAY_PH_ACID "Pompa Acid" +#define D_NEOPOOL_RELAY_PH_BASE "Pompa Base" +#define D_NEOPOOL_RELAY_RX "Poziom Redox" +#define D_NEOPOOL_RELAY_CL "Pompa Chlorine" #define D_NEOPOOL_RELAY_CD "Conductivity" -#define D_NEOPOOL_RELAY_HEATING "Heating" +#define D_NEOPOOL_RELAY_HEATING "Ogrzewanie" #define D_NEOPOOL_RELAY_UV "UV" -#define D_NEOPOOL_RELAY_VALVE "Valve" -#define D_NEOPOOL_RELAY_AUX "Aux" -#define D_NEOPOOL_TIME "Time" -#define D_NEOPOOL_FILT_MODE "Filtration mode" +#define D_NEOPOOL_RELAY_VALVE "Zawór" +#define D_NEOPOOL_RELAY_AUX "Uniwersalny" +#define D_NEOPOOL_TIME "Czas" +#define D_NEOPOOL_FILT_MODE "Tryb filtracji" #define D_NEOPOOL_CELL_RUNTIME "Cell runtime" #define D_NEOPOOL_POLARIZATION "Pol" // Sensor status #define D_NEOPOOL_PR_OFF "PrOff" #define D_NEOPOOL_SETPOINT_OK "Ok" -#define D_NEOPOOL_COVER "Cover" -#define D_NEOPOOL_SHOCK "Boost" -#define D_NEOPOOL_STATUS_ON "ON" -#define D_NEOPOOL_STATUS_OFF "OFF" -#define D_NEOPOOL_STATUS_WAIT "WAIT" -#define D_NEOPOOL_STATUS_TANK "TANK" -#define D_NEOPOOL_STATUS_FLOW "Flow" -#define D_NEOPOOL_LOW "Low" +#define D_NEOPOOL_COVER "Okładka" +#define D_NEOPOOL_SHOCK "Wzmocnienie" +#define D_NEOPOOL_STATUS_ON "ZAŁĄCZONY" +#define D_NEOPOOL_STATUS_OFF "WYŁĄCZONY" +#define D_NEOPOOL_STATUS_WAIT "CZEKAI" +#define D_NEOPOOL_STATUS_TANK "ZBIORNIK" +#define D_NEOPOOL_STATUS_FLOW "Przepływ" +#define D_NEOPOOL_LOW "Niski" #define D_NEOPOOL_FLOW1 "FL1" #define D_NEOPOOL_FLOW2 "FL2" -#define D_NEOPOOL_PH_HIGH "too high" // ph Alarms -#define D_NEOPOOL_PH_LOW "too low" +#define D_NEOPOOL_PH_HIGH "za wysoki" // ph Alarms +#define D_NEOPOOL_PH_LOW "za niski" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "czas pompowania przekroczony" // xsns_106_gdk101.ino @@ -1284,18 +1284,18 @@ #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" // xsns_102_ld2410.ino -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" -#define D_MOVING_ENERGY_T "Moving target" -#define D_STATIC_ENERGY_T "Static target" -#define D_LD2410_PIN_STATE "Output pin state" -#define D_LD2410_LIGHT "Light sensor" +#define D_MOVING_DISTANCE "Dystans Przesówu" +#define D_STATIC_DISTANCE "Dystans Statyczny" +#define D_DETECT_DISTANCE "Wykryj Dystans" +#define D_MOVING_ENERGY_T "Cel przesówu" +#define D_STATIC_ENERGY_T "Cel statyczny" +#define D_LD2410_PIN_STATE "Stan wyjść pin" +#define D_LD2410_LIGHT "Czujnik światła" // xsns_115_wooliis.ino #define D_IMPORT "Import" #define D_EXPORT "Export" -#define D_CHARGING "Charging" -#define D_CAPACITY "Capacity" +#define D_CHARGING "Ładowanie" +#define D_CAPACITY "Pojemność" #endif // _LANGUAGE_PL_PL_D_H_ From 1dff29f36701977cb7af460e4ada70213c6fd9c8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 14 Nov 2024 09:56:49 +0100 Subject: [PATCH 127/205] Update changelogs --- CHANGELOG.md | 2 +- RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6bcfcdea..d776ec2b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Matter provisioning with matter.js controller (#22470) -- Prevent crashing when `display.ini` is missing end `#` +- Prevent crashing when `display.ini` is missing end `#` (#22471) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 094ea970d..eac5e949c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -161,6 +161,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Fixed - FUNC_COMMAND linked list command buffer corruption by shutter driver +- Prevent crashing when `display.ini` is missing end `#` [#22471](https://github.com/arendst/Tasmota/issues/22471) - Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) - Mitsubishi Electric HVAC Standby Stage for MiElHVAC [#22430](https://github.com/arendst/Tasmota/issues/22430) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) From aeceace546f2d942e45e2a17fcd2bc16b6686c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 15 Nov 2024 13:23:57 -0100 Subject: [PATCH 128/205] Add emulation radio and hidden file checkbox labels (#22432) --- tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index a2bbed1ac..a7ad95d34 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -2620,7 +2620,7 @@ void HandleOtherConfiguration(void) { if (i == EMUL_HUE) { i++; } #endif if (i < EMUL_MAX) { - WSContentSend_P(PSTR("%s %s
"), // Different id only used for labels + WSContentSend_P(PSTR("
"), // Different id only used for labels i, i, (i == Settings->flag2.emulation) ? PSTR(" checked") : "", GetTextIndexed(stemp, sizeof(stemp), i, kEmulationOptions), diff --git a/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino b/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino index 5c27384fe..27c97ab85 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino @@ -1117,7 +1117,7 @@ const char UFS_FORM_FILE_UPGb[] PROGMEM = "" ""; const char UFS_FORM_FILE_UPGb1[] PROGMEM = - "" D_SHOW_HIDDEN_FILES ""; + ""; const char UFS_FORM_FILE_UPGb2[] PROGMEM = "" From ef7cd80ed84ba0236bf2b9a59d3d0683336c477b Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Fri, 15 Nov 2024 15:27:46 +0100 Subject: [PATCH 129/205] Update pl_PL.h (#22490) * Update pl_PL.h More PL translations * Update pl_PL.h --- tasmota/language/pl_PL.h | 98 ++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 7d2cc19b4..f30d94fb1 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -257,7 +257,7 @@ // xdrv_02_webserver.ino #define D_NOSCRIPT "Aby korzystać z Tasmota, włącz obsługę JavaScript" -#define D_SAFEBOOT "SAFEBOOT" +#define D_SAFEBOOT "Bezpieczny rozruch" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Oprogramowanie MINIMAL
proszę uaktualnić" #define D_WEBSERVER_ACTIVE_ON "Aktywny serwer Web" #define D_WITH_IP_ADDRESS "z adresem IP" @@ -417,11 +417,11 @@ #define D_NEED_USER_AND_PASSWORD "Wymagany użytkownik=&hasło=" // xdrv_01_mqtt.ino -#define D_FINGERPRINT "Weryfikuj odcisk TLS..." +#define D_FINGERPRINT "Weryfikacja klucza TLS..." #define D_TLS_CONNECT_FAILED_TO "Nieudane połączenie TLS do" #define D_RETRY_IN "Spróbuj ponownie" -#define D_VERIFIED "Zweryfikowano odcisk" -#define D_INSECURE "Nieprawidłowe połączenie z powodu błędnego odcisku TLS" +#define D_VERIFIED "Zweryfikowano" +#define D_INSECURE "Nieprawidłowe połączenie z powodu błędnego klucza TLS" #define D_CONNECT_FAILED_TO "Nie udało się nawiązać połączenia" // xplg_wemohue.ino @@ -509,12 +509,12 @@ #define D_ZIGBEE_GENERATE_KEY "generuj losowo klucz sieci Zigbee" #define D_ZIGBEE_UNKNOWN_DEVICE "Nieznane urządzenie" #define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Nieznany atrybut" -#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint" +#define D_ZIGBEE_UNKNOWN_ENDPOINT "Nieznany punkt końcowy" #define D_ZIGBEE_INVALID_PARAM "Zły parametr" #define D_ZIGBEE_MISSING_PARAM "Brak parametrów" #define D_ZIGBEE_UNKNWON_ATTRIBUTE "Nieznana nazwa atrybutu (ignoruję): %s" #define D_ZIGBEE_TOO_MANY_CLUSTERS "Nie więcej niż jeden cluster id na komendę" -#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints" +#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Konflikt doselowych punktów końcowych" #define D_ZIGBEE_WRONG_DELIMITER "Błędny delimiter autoryzacji" #define D_ZIGBEE_UNRECOGNIZED_COMMAND "Nieznana komenda zigbee: %s" #define D_ZIGBEE_TOO_MANY_COMMANDS "Tylko 1 komenda dozwolona (%d)" @@ -554,21 +554,21 @@ #define D_DEVICE_OUTPUT "Wyjście" // xdrv_39_thermostat.ino, xdrv_85_esp32_ble_eq3_trv.ino -#define D_THERMOSTAT "Thermostat" -#define D_THERMOSTAT_SET_POINT "Set Point Temperature" -#define D_THERMOSTAT_SENSOR "Current Temperature" -#define D_THERMOSTAT_GRADIENT "Gradient Temperature" -#define D_THERMOSTAT_DUTY_CYCLE "Duty cycle" -#define D_THERMOSTAT_VALVE_POSITION "Valve Position" -#define D_THERMOSTAT_CYCLE_TIME "Cycle time" -#define D_THERMOSTAT_PI_AUTOTUNE "PI Auto tuning" -#define D_THERMOSTAT_CONTROL_METHOD "Control method" -#define D_THERMOSTAT_RAMP_UP "Ramp up" +#define D_THERMOSTAT "Termostat" +#define D_THERMOSTAT_SET_POINT "Temperatura zadana" +#define D_THERMOSTAT_SENSOR "Temperatura aktualna" +#define D_THERMOSTAT_GRADIENT "Rozdzielczość temperatury" +#define D_THERMOSTAT_DUTY_CYCLE "Cykl pracy" +#define D_THERMOSTAT_VALVE_POSITION "Pozycja zaworu" +#define D_THERMOSTAT_CYCLE_TIME "Czas cyklu" +#define D_THERMOSTAT_PI_AUTOTUNE "PI Auto strojenie" +#define D_THERMOSTAT_CONTROL_METHOD "Metoda kontroli" +#define D_THERMOSTAT_RAMP_UP "Przyspieszanie" #define D_THERMOSTAT_PI "PI" -#define D_THERMOSTAT_AUTOTUNE "Autotune" -#define D_THERMOSTAT_RAMP_UP_HYBRID "Ramp up (Hybrid)" +#define D_THERMOSTAT_AUTOTUNE "Automatyczne strojenie" +#define D_THERMOSTAT_RAMP_UP_HYBRID "Przyspieszanie (Hybrid)" #define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" -#define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" +#define D_THERMOSTAT_AUTOTUNE_HYBRID "Automatyczne strojenie (Hybrid)" // xdrv_79_esp32_ble.ino #define D_CONFIGURE_BLE "Konfiguracja BLE" @@ -616,10 +616,10 @@ #define D_GZ_AXIS "Odchylenie Oś-Z" // xsns_33_QMC5883L.ino -#define D_MX "Induction X-Axis" -#define D_MY "Induction Y-Axis" -#define D_MZ "Induction Z-Axis" -#define D_MAGNETICFLD "Magnetic Induction" +#define D_MX "Indukcja X-Axis" +#define D_MY "Inducja Y-Axis" +#define D_MZ "Inducja Z-Axis" +#define D_MAGNETICFLD "Indukcja magnetyczna" // xsns_34_hx711.ino #define D_HX_CAL_REMOVE "Usuń wagę" @@ -671,22 +671,22 @@ #define D_CHIPTEMPERATURE "Temperatura Chipa" // xsns_60_GPS -#define D_LATITUDE "Latitude" -#define D_LONGITUDE "Longitude" +#define D_LATITUDE "Szerokość" +#define D_LONGITUDE "Długość" #define D_HORIZONTAL_ACCURACY "Horizontal Accuracy" -#define D_ALTITUDE "Altitude" -#define D_VERTICAL_ACCURACY "Vertical Accuracy" -#define D_SPEED "Speed" -#define D_SPEED_ACCURACY "Speed Accuracy" -#define D_HEADING "Heading" -#define D_HEADING_ACCURACY "Heading Accuracy" -#define D_SAT_FIX "Satellite Fix" - #define D_SAT_FIX_NO_FIX "None" - #define D_SAT_FIX_DEAD_RECK "Dead reckoning" +#define D_ALTITUDE "Dokładność pozioma" +#define D_VERTICAL_ACCURACY "Dokładność pionowa" +#define D_SPEED "Prędkość" +#define D_SPEED_ACCURACY "Dokładność prędkości" +#define D_HEADING "Nagłówek" +#define D_HEADING_ACCURACY "Dokładność nagłówka" +#define D_SAT_FIX "Satelita" + #define D_SAT_FIX_NO_FIX "Żadne" + #define D_SAT_FIX_DEAD_RECK "Martwe pole" #define D_SAT_FIX_2D "2D" #define D_SAT_FIX_3D "3D" - #define D_SAT_FIX_GPS_DEAD "GPS and dead reckoning" - #define D_SAT_FIX_TIME "Time only fix" + #define D_SAT_FIX_GPS_DEAD "GPS i martwe pole" + #define D_SAT_FIX_TIME "Tylko czas" // tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box #define D_SENSOR_NONE "Brak" @@ -721,7 +721,7 @@ #define D_SENSOR_LED_LINK "Led link" // Suffix "i" #define D_SENSOR_PWM "Obroty" // Suffix "1" #define D_SENSOR_COUNTER "Licznik" // Suffix "1" -#define D_SENSOR_INTERRUPT "Interrupt" +#define D_SENSOR_INTERRUPT "Zakłucenia" #define D_SENSOR_INPUT "Input" #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" @@ -1003,7 +1003,7 @@ #define D_GPIO_DINGTIAN_RCK "Dingtian RCK" #define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" -#define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_FLOWRATEMETER "Przepływ" #define D_SENSOR_ME007_TRIG "ME007 Tri" #define D_SENSOR_ME007_RX "ME007 Rx" #define D_SENSOR_TUYAMCUBR_TX "TuyaMCUBr Tx" @@ -1210,9 +1210,9 @@ #define D_FP_UNKNOWNERROR "Błąd" // Any other error // xsns_96_flowratemeter.ino -#define D_FLOWRATEMETER_NAME "Flowrate" -#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today" -#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today" +#define D_FLOWRATEMETER_NAME "Przepływ" +#define D_FLOWRATEMETER_AMOUNT_TODAY "Wartość dzisiaj" +#define D_FLOWRATEMETER_DURATION_TODAY "Czas trwania dzisiaj" // xsns_83_neopool.ino #define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names @@ -1231,18 +1231,18 @@ #define D_NEOPOOL_FILTRATION_AUTO "Auto" #define D_NEOPOOL_FILTRATION_HEATING "Ogrzewanie" #define D_NEOPOOL_FILTRATION_SMART "Smart" -#define D_NEOPOOL_FILTRATION_INTELLIGENT "Intelligent" -#define D_NEOPOOL_FILTRATION_BACKWASH "Backwash" -#define D_NEOPOOL_FILTRATION_NONE "" // Filtration speed level +#define D_NEOPOOL_FILTRATION_INTELLIGENT "Inteligentny" +#define D_NEOPOOL_FILTRATION_BACKWASH "Płukanie wsteczne" +#define D_NEOPOOL_FILTRATION_NONE "żaden" // Filtration speed level #define D_NEOPOOL_FILTRATION_SLOW "wolny" #define D_NEOPOOL_FILTRATION_MEDIUM "średni" #define D_NEOPOOL_FILTRATION_FAST "szybki" #define D_NEOPOOL_TYPE "Typ" // Sensor & relais names #define D_NEOPOOL_REDOX "Redox" -#define D_NEOPOOL_CHLORINE "Chlorine" -#define D_NEOPOOL_CONDUCTIVITY "Conductivity" -#define D_NEOPOOL_IONIZATION "Ionization" -#define D_NEOPOOL_HYDROLYSIS "Hydrolysis" +#define D_NEOPOOL_CHLORINE "Chlor" +#define D_NEOPOOL_CONDUCTIVITY "Przewodność" +#define D_NEOPOOL_IONIZATION "Jonizacja" +#define D_NEOPOOL_HYDROLYSIS "Hydroliza" #define D_NEOPOOL_RELAY "Przekaźnik" #define D_NEOPOOL_RELAY_FILTRATION "Filtrowanie" // Relay assignment #define D_NEOPOOL_RELAY_LIGHT "Światło" @@ -1250,7 +1250,7 @@ #define D_NEOPOOL_RELAY_PH_BASE "Pompa Base" #define D_NEOPOOL_RELAY_RX "Poziom Redox" #define D_NEOPOOL_RELAY_CL "Pompa Chlorine" -#define D_NEOPOOL_RELAY_CD "Conductivity" +#define D_NEOPOOL_RELAY_CD "Przewodność" #define D_NEOPOOL_RELAY_HEATING "Ogrzewanie" #define D_NEOPOOL_RELAY_UV "UV" #define D_NEOPOOL_RELAY_VALVE "Zawór" From 996ea17fb6957a4bf4521d0031c8b42f96818ee2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:12:17 +0100 Subject: [PATCH 130/205] prep support TM1640 --- tasmota/include/tasmota_template.h | 6 ++++++ tasmota/language/af_AF.h | 2 ++ tasmota/language/bg_BG.h | 2 ++ tasmota/language/ca_AD.h | 2 ++ tasmota/language/cs_CZ.h | 2 ++ tasmota/language/de_DE.h | 2 ++ tasmota/language/el_GR.h | 2 ++ tasmota/language/en_GB.h | 2 ++ tasmota/language/es_ES.h | 2 ++ tasmota/language/fr_FR.h | 2 ++ tasmota/language/fy_NL.h | 2 ++ tasmota/language/he_HE.h | 2 ++ tasmota/language/hu_HU.h | 2 ++ tasmota/language/it_IT.h | 2 ++ tasmota/language/ko_KO.h | 2 ++ tasmota/language/nl_NL.h | 2 ++ tasmota/language/pl_PL.h | 2 ++ tasmota/language/pt_BR.h | 2 ++ tasmota/language/pt_PT.h | 2 ++ tasmota/language/ro_RO.h | 2 ++ tasmota/language/ru_RU.h | 2 ++ tasmota/language/sk_SK.h | 2 ++ tasmota/language/sv_SE.h | 2 ++ tasmota/language/tr_TR.h | 2 ++ tasmota/language/uk_UA.h | 2 ++ tasmota/language/vi_VN.h | 2 ++ tasmota/language/zh_CN.h | 2 ++ tasmota/language/zh_TW.h | 2 ++ 28 files changed, 60 insertions(+) diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 3788d9a8b..d4c324cfb 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -227,6 +227,7 @@ enum UserSelectablePins { GPIO_DALI_RX_INV, GPIO_DALI_TX_INV, // DALI GPIO_LD2410S_TX, GPIO_LD2410S_RX, // HLK-LD2410S GPIO_I2C_SER_TX, GPIO_I2C_SER_RX, // I2C via Serial using SC18IM704 protocol (xdrv74) + GPIO_TM1640CLK, GPIO_TM1640DIN, // TM1640 (16 x seven-segment LED controler) GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage with max 2045 @@ -501,6 +502,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DALI_RX "_i|" D_SENSOR_DALI_TX "_i|" D_SENSOR_LD2410S_TX "|" D_SENSOR_LD2410S_RX "|" D_SENSOR_I2C_SER_TX "|" D_SENSOR_I2C_SER_RX "|" + D_SENSOR_TM1640_CLK "|" D_SENSOR_TM1640_DIN "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -732,6 +734,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_TM1638DIO), AGPIO(GPIO_TM1638STB), #endif // USE_DISPLAY_TM1637 +#ifdef USE_DISPLAY_TM1640 + AGPIO(GPIO_TM1640CLK), + AGPIO(GPIO_TM1640DIN), +#endif // USE_DISPLAY_TM1640 AGPIO(GPIO_BACKLIGHT), // Display backlight control AGPIO(GPIO_OLED_RESET), // OLED Display Reset #ifdef ESP32 diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index e863df45c..0042913a8 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 50560e359..e4adb6dbb 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index 93ce54f52..5c4638ddc 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index cf3b917f0..f09bb97d3 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index a25a7030b..04096ee3c 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 3194feeec..cfe3e1a39 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 9133db349..f379bd8e4 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index bcba22c7e..ff49b3058 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 1a9f67add..1b07f5e8b 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 Clk" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 Stb" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 Din" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 Clk" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index ced0b6087..189e2297a 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index ed49d923a..6a04467ac 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 50bc0c9c7..9f07ff5cc 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index dd4d5a1f6..a58afd364 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 - CLK" #define D_SENSOR_TM1638_DIO "TM1638 - DIO" #define D_SENSOR_TM1638_STB "TM1638 - STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 - DIN" #define D_SENSOR_MAX7219_CS "MAX7219 - CS" #define D_SENSOR_MAX7219_CLK "MAX7219 - CLK" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 8c19dbffe..d47bee947 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index f3143e094..dac4c6eee 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index f30d94fb1..108daccc2 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 186f156ad..4dfaf2058 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index e75bdc3c3..4735ffe3f 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 982d7599f..96a0f506d 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index bf2148662..0a70d129c 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -789,6 +789,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 7e95c1680..91ba8d635 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index c2988b36f..8bf23eb8d 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 7880d2ce0..d73fbd1ab 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 42b14bec8..0cf2ac690 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 62762814a..4b625a7c0 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 28699b933..70d2c5d97 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index b65007bf0..2b721c2ab 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -788,6 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 CLK" #define D_SENSOR_TM1638_DIO "TM1638 DIO" #define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 DIN" #define D_SENSOR_MAX7219_CS "MAX7219 CS" #define D_SENSOR_MAX7219_CLK "MAX7219 CLK" From 0947860c831de00f8f05aa474f548bcc52ce8127 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Fri, 15 Nov 2024 17:57:22 +0100 Subject: [PATCH 131/205] Update pl_PL.h (#22491) * Update pl_PL.h Fix typo and gramma * Update pl_PL.h --- tasmota/language/pl_PL.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 108daccc2..e48f1e00d 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -116,7 +116,7 @@ #define D_GATEWAY "Brama" #define D_GROUP "Grupa" #define D_HOST "Serwer" -#define D_HALL_EFFECT "Efekt Hall" +#define D_HALL_EFFECT "Efekt Hall'a" #define D_HEATINDEX "Indeks ciepła" #define D_HOSTNAME "Nazwa serwera" #define D_HUMIDITY "Wilgotność" @@ -617,8 +617,8 @@ // xsns_33_QMC5883L.ino #define D_MX "Indukcja X-Axis" -#define D_MY "Inducja Y-Axis" -#define D_MZ "Inducja Z-Axis" +#define D_MY "Indukcja Y-Axis" +#define D_MZ "Indukcja Z-Axis" #define D_MAGNETICFLD "Indukcja magnetyczna" // xsns_34_hx711.ino @@ -721,7 +721,7 @@ #define D_SENSOR_LED_LINK "Led link" // Suffix "i" #define D_SENSOR_PWM "Obroty" // Suffix "1" #define D_SENSOR_COUNTER "Licznik" // Suffix "1" -#define D_SENSOR_INTERRUPT "Zakłucenia" +#define D_SENSOR_INTERRUPT "Zakłócenia" #define D_SENSOR_INPUT "Input" #define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_MHZ_RX "MHZ Rx" @@ -1267,7 +1267,7 @@ #define D_NEOPOOL_SHOCK "Wzmocnienie" #define D_NEOPOOL_STATUS_ON "ZAŁĄCZONY" #define D_NEOPOOL_STATUS_OFF "WYŁĄCZONY" -#define D_NEOPOOL_STATUS_WAIT "CZEKAI" +#define D_NEOPOOL_STATUS_WAIT "CZEKAJ" #define D_NEOPOOL_STATUS_TANK "ZBIORNIK" #define D_NEOPOOL_STATUS_FLOW "Przepływ" #define D_NEOPOOL_LOW "Niski" @@ -1286,10 +1286,10 @@ #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" // xsns_102_ld2410.ino -#define D_MOVING_DISTANCE "Dystans Przesówu" +#define D_MOVING_DISTANCE "Dystans Przesuwu" #define D_STATIC_DISTANCE "Dystans Statyczny" #define D_DETECT_DISTANCE "Wykryj Dystans" -#define D_MOVING_ENERGY_T "Cel przesówu" +#define D_MOVING_ENERGY_T "Cel przesuwu" #define D_STATIC_ENERGY_T "Cel statyczny" #define D_LD2410_PIN_STATE "Stan wyjść pin" #define D_LD2410_LIGHT "Czujnik światła" From d3df759514e3cd54b700968e3e9087b69ad5f131 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Fri, 15 Nov 2024 20:32:33 +0100 Subject: [PATCH 132/205] Italian language update (#22493) --- tasmota/language/it_IT.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index a58afd364..1c614468e 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.4.0.1 - Last update 31.10.2024 + * Updated until v9.4.0.1 - Last update 15.11.2024 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -788,8 +788,8 @@ #define D_SENSOR_TM1638_CLK "TM1638 - CLK" #define D_SENSOR_TM1638_DIO "TM1638 - DIO" #define D_SENSOR_TM1638_STB "TM1638 - STB" -#define D_SENSOR_TM1640_CLK "TM1640 CLK" -#define D_SENSOR_TM1640_DIN "TM1640 DIN" +#define D_SENSOR_TM1640_CLK "TM1640 - CLK" +#define D_SENSOR_TM1640_DIN "TM1640 - DIN" #define D_SENSOR_MAX7219_DIN "MAX7219 - DIN" #define D_SENSOR_MAX7219_CS "MAX7219 - CS" #define D_SENSOR_MAX7219_CLK "MAX7219 - CLK" From 09c43fa72964c633c7eadcb03b18a311323ff6e5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 15 Nov 2024 20:44:16 +0100 Subject: [PATCH 133/205] fix compile when no `core_version` exists (#22494) --- lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h index 3f0a892a5..0ca24ec00 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h @@ -20,7 +20,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#ifndef ESP32_STAGE // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option +#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) +#endif // ESP32_STAGE #ifndef wificlientlightbearssl_h #define wificlientlightbearssl_h From de45fda781f5b5f502459abf776286f387e87989 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 16 Nov 2024 14:44:18 +0100 Subject: [PATCH 134/205] Add minimum defaults in case of error --- tasmota/tasmota_support/settings.ino | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index db5aa35c2..62157156d 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -858,6 +858,8 @@ void SettingsLoad(void) { settings_crc32 = GetSettingsCrc32(); #endif // FIRMWARE_MINIMAL + SettingsMinimum(); // Set life-saving parameters if out-of-range due to reconfig Settings Area + RtcSettingsLoad(1); } @@ -928,6 +930,14 @@ void SettingsSdkErase(void) { /********************************************************************************************/ +void SettingsMinimum(void) { + // Set life-saving parameters if out-of-range due to reconfig Settings Area + if (Settings->dns_timeout < 100) { Settings->dns_timeout = DNS_TIMEOUT; } + if (Settings->mqtt_keepalive < 1) { Settings->mqtt_keepalive = MQTT_KEEPALIVE; } + if (Settings->mqtt_socket_timeout < 1) { Settings->mqtt_socket_timeout = MQTT_SOCKET_TIMEOUT; } + if (Settings->mqtt_wifi_timeout < 1) { Settings->mqtt_wifi_timeout = MQTT_WIFI_CLIENT_TIMEOUT / 100; } +} + void SettingsDefault(void) { AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_CONFIG D_USE_DEFAULTS)); SettingsDefaultSet1(); From 5de16c1cca3ee0b1ccb5cef00e9c75ce5eb37e99 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 16 Nov 2024 15:02:01 +0100 Subject: [PATCH 135/205] Add settingsminimum --- tasmota/tasmota.ino | 1 + tasmota/tasmota_support/settings.ino | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 16191bb1f..1ec2500aa 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -566,6 +566,7 @@ void setup(void) { SettingsLoad(); SettingsDelta(); + SettingsMinimum(); // Set life-saving parameters if out-of-range due to reconfig Settings Area OsWatchInit(); diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index 62157156d..abfb85484 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -858,8 +858,6 @@ void SettingsLoad(void) { settings_crc32 = GetSettingsCrc32(); #endif // FIRMWARE_MINIMAL - SettingsMinimum(); // Set life-saving parameters if out-of-range due to reconfig Settings Area - RtcSettingsLoad(1); } From 14c0a42203d9664bd4aa4054ace500755d240e99 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 16 Nov 2024 17:47:18 +0100 Subject: [PATCH 136/205] Bump version v14.3.0.7 - ESP32 max number of supported switches/buttons/relays from 28 to 32 - ESP32 max number of interlocks from 14 to 16 --- CHANGELOG.md | 15 +- RELEASENOTES.md | 4 +- .../HTTP_SCRIPT_MODULE_TEMPLATE.h | 24 +-- .../HTTP_SCRIPT_MODULE_TEMPLATE.h | 2 +- tasmota/include/tasmota.h | 13 +- tasmota/include/tasmota_template.h | 174 +++++++++--------- tasmota/include/tasmota_types.h | 34 ++-- tasmota/include/tasmota_version.h | 2 +- tasmota/tasmota_support/settings.ino | 10 + tasmota/tasmota_support/support.ino | 1 + tasmota/tasmota_support/support_command.ino | 4 +- 11 files changed, 151 insertions(+), 132 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d776ec2b4..dcef330d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,20 +3,27 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.3.0.6] +## [14.3.0.7] ### Added -- Add command ``WebColor20`` to control color of Button when Off ### Breaking Changed +### Fixed + +### Removed + ### Changed +- ESP32 max number of supported switches/buttons/relays from 28 to 32 +- ESP32 max number of interlocks from 14 to 16 + +## [14.3.0.6] 20241116 +### Added +- Add command ``WebColor20`` to control color of Button when Off ### Fixed - Matter provisioning with matter.js controller (#22470) - Prevent crashing when `display.ini` is missing end `#` (#22471) -### Removed - ## [14.3.0.5] 20241111 ### Added - ESP32 MI32 legacy add config operations (#22458) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index eac5e949c..ed100cf8d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -114,7 +114,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.3.0.6 +## Changelog v14.3.0.7 ### Added - Add command ``WebColor20`` to control color of Button when Off - DALI support for short addresses (gear) and groups @@ -157,6 +157,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default - Shutter optimized behavior to publish shutter data with sensor request [#22353](https://github.com/arendst/Tasmota/issues/22353) +- ESP32 max number of supported switches/buttons/relays from 28 to 32 +- ESP32 max number of interlocks from 14 to 16 - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed diff --git a/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h b/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h index e7f059b0b..99c40b1ac 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h @@ -2,7 +2,7 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 602; +const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 589; const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\xD4\x2B\xC7\x83\x02\xF8\x3A\xDC\xE4\x1B\x3B\xBA\x75\x1A\x8E\xF1" "\xED\x33\xBF\xAC\x3E\x09\x81\x8B\x1A\xFA\x8E\x81\xFD\xDD\x32\x61\x31\xAF\xA8\xEE" "\x9F\x78\x32\xB7\x38\xFB\x3B\xC7\x8C\x3A\x53\x36\x51\x07\x9D\x4F\xA8\xF9\xA7\x83" @@ -15,16 +15,16 @@ const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\ "\x0C\x3A\x7D\x8D\xC3\x36\x08\x3B\x70\x24\xE0\x87\x78\xF0\x7B\x82\x3E\x0A\x04\xAC" "\xC8\xE3\x3C\x16\x9E\x81\x1E\x34\xED\x9D\xB3\xBC\x7B\x43\x3E\x0A\xF1\xEF\x69\xEF" "\x82\x17\x2A\x01\xE7\x8D\x30\x77\x6C\xF8\x7C\x0C\xEF\x1E\xD1\xC0\x89\x50\xE3\x70" - "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x21\x64\x47\x21" - "\xE0\xB4\xF4\x3E\x0E\x04\x2C\x8D\x9D\xD3\xBB\xA7\xA1\xC8\xCE\xF1\xDA\x3B\xA7\xD9" - "\xDC\x3E\xCE\xD9\x69\xDE\x3C\xF4\xEA\xA3\xBC\x78\x3D\xCC\x71\xDD\x3E\xC5\x1F\x67" - "\x6C\x78\xEF\x1D\x0C\xEC\x21\x6C\xF8\x2C\xED\x9C\x87\x82\xA3\xA7\xA8\xC8\x26\x74" - "\x33\xDF\x68\xED\x0B\x68\xC8\xF8\x77\x47\x1F\x87\x19\xDE\x3B\x47\xD9\xF6\x79\x9F" - "\x64\x2B\x44\x11\xF1\xF6\x08\xDC\x58\xF8\xD0\xEE\xF8\xEA\x1E\x04\x3E\x42\xF3\xC7" - "\x4F\xB1\x81\x58\x6C\xEE\x9D\x87\xB8\xE5\x1D\x84\x3C\x75\x1E\xC3\xD0\x10\x78\x4B" - "\x40\x83\x9E\x9F\x67\xB0\xEF\x02\x35\xD3\x96\x76\x10\xF1\xD4\x7B\x0F\x43\xB0\x10" - "\x6F\x1F\x87\xB0\xEF\x1E\x18\xE3\xBA\x7D\x8F\x1F\x67\x6C\x78\xEF\x1D\x37\xB9\xFC" - "\x85\x15\x10\xD2\x08\xF9\x80\x8D\x48\x10\x72\x13\xBA\x3C\x7A\x1C\x48\xEF\x1D\xA2" - "\x04\x3E\x47\x4F\x3F\x1E\x34\xC0\x20\xD0\x3D\xA0\x85\xC9\xF9\xE0\xF7\x1E\xE3"; + "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x23\x64\x47\xC1" + "\xC0\x85\x91\xB3\xBB\xA7\x6C\xE4\x3A\x8A\x8E\xF1\xE0\xF7\x31\xC7\x74\xFB\x14\x7D" + "\x9D\xB1\xE3\xBC\x74\x33\xB0\x85\xB3\xE0\xB3\xB6\x72\x1E\x0A\x8E\x9E\xA3\x20\x99" + "\xD0\xCF\x7D\xA3\xB4\x2D\xA3\x23\xE1\xDD\x1C\x7E\x1C\x67\x78\xED\x1F\x67\xD9\xE6" + "\x7D\x90\xAD\x10\x47\xC7\xD8\x23\x71\x49\xE3\x43\xBB\xE3\xA8\x78\x10\xF8\xFE\xCF" + "\x1D\x3E\xC6\x05\x61\xB3\xBA\x76\x1E\xE3\x94\x76\x10\xF1\xD4\x7B\x0F\x40\x41\xE0" + "\xF9\x02\x0E\x7A\x7D\x9E\xC3\xBC\x08\xD7\x4E\x59\xD8\x43\xC7\x51\xEC\x3D\x0E\xC0" + "\x41\xBC\x7E\x1E\xC3\xBC\x78\x63\x8E\xE9\xF6\x3C\x7D\x9D\xB1\xE3\xBC\x74\xDE\xE7" + "\xF2\x14\x54\x43\x48\x23\xE6\x02\x35\x20\x41\xC8\x4E\xE8\xF1\xE8\x71\x23\xBC\x76" + "\x88\x10\xF9\x10\x3C\xFC\x78\xD3\x2A\x01\x83\x40\xF6\x82\x17\x26\x47\x83\xDC\x7B" + "\x8D"; #define HTTP_SCRIPT_MODULE_TEMPLATE Decompress(HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED,HTTP_SCRIPT_MODULE_TEMPLATE_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h b/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h index fd52afcc0..0fcd77c51 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h @@ -12,7 +12,7 @@ const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM = "l=hs.length;" // Find max indexes for s "for(i=0;i>=5;" // Add options - "for(i=1;i<=b;i++){ce((i<10)?(' '+i):i,t);}" + "for(i=0;i<=b;i++){ce(i+1,t);}" // Add index 1 to 32 "eb('h'+g).value=u+1;" // Set selected value "t.style.visibility=(b>0)?'':'hidden';" "}" diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index ca775b88e..81ce401f6 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -38,7 +38,6 @@ const uint32_t POWER_SIZE = 32; // Power (relay) bit count * Constants \*********************************************************************************************/ -// Why 28? Because in addition to relays there may be lights and uint32_t bitmap can hold up to 32 devices #ifdef ESP8266 const uint8_t MAX_RELAYS = 8; // Max number of relays selectable on GPIO const uint8_t MAX_INTERLOCKS = 4; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) @@ -46,17 +45,17 @@ const uint8_t MAX_SWITCHES = 8; // Max number of switches selectable const uint8_t MAX_KEYS = 8; // Max number of keys or buttons selectable on GPIO #endif // ESP8266 #ifdef ESP32 -const uint8_t MAX_RELAYS = 28; // Max number of relays selectable on GPIO -const uint8_t MAX_INTERLOCKS = 14; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) -const uint8_t MAX_SWITCHES = 28; // Max number of switches selectable on GPIO -const uint8_t MAX_KEYS = 28; // Max number of keys or buttons selectable on GPIO +const uint8_t MAX_RELAYS = 32; // Max number of relays selectable on GPIO +const uint8_t MAX_INTERLOCKS = 16; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) +const uint8_t MAX_SWITCHES = 32; // Max number of switches selectable on GPIO +const uint8_t MAX_KEYS = 32; // Max number of keys or buttons selectable on GPIO #endif // ESP32 const uint8_t MAX_RELAYS_SET = 32; // Max number of relays const uint8_t MAX_KEYS_SET = 32; // Max number of keys // Changes to the following MAX_ defines will impact settings layout -const uint8_t MAX_INTERLOCKS_SET = 14; // Max number of interlock groups (MAX_RELAYS_SET / 2) -const uint8_t MAX_SWITCHES_SET = 28; // Max number of switches +const uint8_t MAX_INTERLOCKS_SET = 16; // Max number of interlock groups (MAX_RELAYS_SET / 2) +const uint8_t MAX_SWITCHES_SET = 32; // Max number of switches const uint8_t MAX_LEDS = 4; // Max number of leds const uint8_t MAX_PWMS_LEGACY = 5; // Max number of PWM channels in first settings block - Legacy limit for ESP8266, but extended for ESP32 (see below) #ifdef ESP32 // Max number of PWM channels (total including extended) - ESP32 only diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index d4c324cfb..f570f8894 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -509,7 +509,7 @@ const char kSensorNamesFixed[] PROGMEM = D_SENSOR_USER; // Max number of GPIOs -#define MAX_I2C 0 // Display no index if one bus +#define MAX_I2C 1 // Display no index if one bus #ifdef USE_I2C_BUS2 #undef MAX_I2C #define MAX_I2C 2 @@ -533,46 +533,46 @@ const char kSensorNamesFixed[] PROGMEM = const uint16_t kGpioNiceList[] PROGMEM = { GPIO_NONE, // Not used - AGPIO(GPIO_OPTION_A) + MAX_OPTIONS_A, // Device specific options + AGPIO(GPIO_OPTION_A) + MAX_OPTIONS_A -1, // Device specific options #ifdef ESP32 - AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E, // Device module emulation + AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E -1, // Device module emulation #endif - AGPIO(GPIO_KEY1) + MAX_KEYS, // Buttons - AGPIO(GPIO_KEY1_NP) + MAX_KEYS, + AGPIO(GPIO_KEY1) + MAX_KEYS -1, // Buttons + AGPIO(GPIO_KEY1_NP) + MAX_KEYS -1, #ifdef ESP32 - AGPIO(GPIO_KEY1_PD) + MAX_KEYS, + AGPIO(GPIO_KEY1_PD) + MAX_KEYS -1, #endif - AGPIO(GPIO_KEY1_INV) + MAX_KEYS, - AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS, + AGPIO(GPIO_KEY1_INV) + MAX_KEYS -1, + AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS -1, #ifdef ESP32 - AGPIO(GPIO_KEY1_INV_PD) + MAX_KEYS, + AGPIO(GPIO_KEY1_INV_PD) + MAX_KEYS -1, #if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2) - AGPIO(GPIO_KEY1_TC) + MAX_KEYS, // Touch button + AGPIO(GPIO_KEY1_TC) + MAX_KEYS -1, // Touch button #endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 #endif - AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches - AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES, + AGPIO(GPIO_SWT1) + MAX_SWITCHES -1, // User connected external switches + AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES -1, #ifdef ESP32 - AGPIO(GPIO_SWT1_PD) + MAX_SWITCHES, + AGPIO(GPIO_SWT1_PD) + MAX_SWITCHES -1, #endif #ifdef ROTARY_V1 - AGPIO(GPIO_ROT1A) + MAX_ROTARIES, // Rotary A Pin - AGPIO(GPIO_ROT1B) + MAX_ROTARIES, // Rotary B Pin - AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES, // Rotary A Pin No Pullup - AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES, // Rotary B Pin No Pullup + AGPIO(GPIO_ROT1A) + MAX_ROTARIES -1, // Rotary A Pin + AGPIO(GPIO_ROT1B) + MAX_ROTARIES -1, // Rotary B Pin + AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES -1, // Rotary A Pin No Pullup + AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES -1, // Rotary B Pin No Pullup #endif - AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays - AGPIO(GPIO_REL1_INV) + MAX_RELAYS, - AGPIO(GPIO_REL1_BI) + MAX_RELAYS, // Bistable (Latching) two coil relays - AGPIO(GPIO_REL1_BI_INV) + MAX_RELAYS, - AGPIO(GPIO_LED1) + MAX_LEDS, // Leds - AGPIO(GPIO_LED1_INV) + MAX_LEDS, + AGPIO(GPIO_REL1) + MAX_RELAYS -1, // Relays + AGPIO(GPIO_REL1_INV) + MAX_RELAYS -1, + AGPIO(GPIO_REL1_BI) + MAX_RELAYS -1, // Bistable (Latching) two coil relays + AGPIO(GPIO_REL1_BI_INV) + MAX_RELAYS -1, + AGPIO(GPIO_LED1) + MAX_LEDS -1, // Leds + AGPIO(GPIO_LED1_INV) + MAX_LEDS -1, #ifdef USE_COUNTER - AGPIO(GPIO_CNTR1) + MAX_COUNTERS, // Counters - AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS, + AGPIO(GPIO_CNTR1) + MAX_COUNTERS -1, // Counters + AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS -1, #endif - AGPIO(GPIO_PWM1) + MAX_PWMS, // RGB Red or C Cold White - AGPIO(GPIO_PWM1_INV) + MAX_PWMS, // or extended PWM for ESP32 + AGPIO(GPIO_PWM1) + MAX_PWMS -1, // RGB Red or C Cold White + AGPIO(GPIO_PWM1_INV) + MAX_PWMS -1, // or extended PWM for ESP32 #ifdef USE_BUZZER AGPIO(GPIO_BUZZER), // Buzzer AGPIO(GPIO_BUZZER_INV), // Inverted buzzer @@ -580,8 +580,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_LEDLNK), // Link led AGPIO(GPIO_LEDLNK_INV), // Inverted link led #ifdef USE_BERRY - AGPIO(GPIO_INPUT) + MAX_SWITCHES, // Pure digital input to be read via Berry - AGPIO(GPIO_INTERRUPT) + MAX_SWITCHES, // Interrupt pins to be catched by Berry + AGPIO(GPIO_INPUT) + MAX_SWITCHES -1, // Pure digital input to be read via Berry + AGPIO(GPIO_INTERRUPT) + MAX_SWITCHES -1, // Interrupt pins to be catched by Berry #endif AGPIO(GPIO_OUTPUT_HI), // Fixed output high AGPIO(GPIO_OUTPUT_LO), // Fixed output low @@ -601,32 +601,32 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #ifdef USE_I2C - AGPIO(GPIO_I2C_SCL) + MAX_I2C, // I2C SCL - AGPIO(GPIO_I2C_SDA) + MAX_I2C, // I2C SDA + AGPIO(GPIO_I2C_SCL) + MAX_I2C -1, // I2C SCL + AGPIO(GPIO_I2C_SDA) + MAX_I2C -1, // I2C SDA #ifdef USE_PCF8574 AGPIO(GPIO_PCF8574_INT), // PCF8574 Interrupt #endif // USE_PCF8574 #ifdef USE_I2C_SERIAL - AGPIO(GPIO_I2C_SER_TX) + MAX_I2C, // I2C via Serial TX - AGPIO(GPIO_I2C_SER_RX) + MAX_I2C, // I2C via Serial RX + AGPIO(GPIO_I2C_SER_TX) + MAX_I2C -1, // I2C via Serial TX + AGPIO(GPIO_I2C_SER_RX) + MAX_I2C -1, // I2C via Serial RX #endif // USE_I2C_SERIAL #endif #if defined(USE_I2S_AUDIO) || defined (USE_I2S) - AGPIO(GPIO_I2S_MCLK) + MAX_I2S, // I2S master clock - AGPIO(GPIO_I2S_BCLK) + MAX_I2S, // I2S bit clock - AGPIO(GPIO_I2S_DOUT) + MAX_I2S, // I2S Out Data - AGPIO(GPIO_I2S_DAC) + 2, // I2S DAC Output - AGPIO(GPIO_I2S_WS) + MAX_I2S, // I2S word select - AGPIO(GPIO_I2S_DIN) + MAX_I2S, // I2S IN Data + AGPIO(GPIO_I2S_MCLK) + MAX_I2S -1, // I2S master clock + AGPIO(GPIO_I2S_BCLK) + MAX_I2S -1, // I2S bit clock + AGPIO(GPIO_I2S_DOUT) + MAX_I2S -1, // I2S Out Data + AGPIO(GPIO_I2S_DAC) + 2 -1, // I2S DAC Output + AGPIO(GPIO_I2S_WS) + MAX_I2S -1, // I2S word select + AGPIO(GPIO_I2S_DIN) + MAX_I2S -1, // I2S IN Data #endif #ifdef USE_SPI - AGPIO(GPIO_SPI_MISO) + MAX_SPI, // SPI MISO - AGPIO(GPIO_SPI_MOSI) + MAX_SPI, // SPI MOSI - AGPIO(GPIO_SPI_CLK) + MAX_SPI, // SPI Clk - AGPIO(GPIO_SPI_CS) + MAX_SPI, // SPI Chip Select - AGPIO(GPIO_SPI_DC) + MAX_SPI, // SPI Data Direction + AGPIO(GPIO_SPI_MISO) + MAX_SPI -1, // SPI MISO + AGPIO(GPIO_SPI_MOSI) + MAX_SPI -1, // SPI MOSI + AGPIO(GPIO_SPI_CLK) + MAX_SPI -1, // SPI Clk + AGPIO(GPIO_SPI_CS) + MAX_SPI -1, // SPI Chip Select + AGPIO(GPIO_SPI_DC) + MAX_SPI -1, // SPI Data Direction #ifdef USE_NRF24 AGPIO(GPIO_NRF24_CS), AGPIO(GPIO_NRF24_DC), @@ -642,7 +642,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MCP2515_CS), #endif // USE_MCP2515 #ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23SXX_CS) + MAX_MCP23XXX, + AGPIO(GPIO_MCP23SXX_CS) + MAX_MCP23XXX -1, #endif // USE_MCP23XXX_DRV #ifdef USE_SPI_LORA AGPIO(GPIO_LORA_CS), @@ -754,11 +754,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_DISPLAY_TM1621_SONOFF #ifdef USE_MAX31865 - AGPIO(GPIO_SSPI_MAX31865_CS1) + MAX_MAX31865S, + AGPIO(GPIO_SSPI_MAX31865_CS1) + MAX_MAX31865S -1, #endif #ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23XXX_INT) + MAX_MCP23XXX, + AGPIO(GPIO_MCP23XXX_INT) + MAX_MCP23XXX -1, #endif #ifdef USE_HDMI_CEC @@ -780,8 +780,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 #endif #ifdef USE_DS18x20 - AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20 - AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB) + MAX_DSB -1, // Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB_OUT) + MAX_DSB -1, // Pseudo Single wire DS18B20 or DS18S20 #endif // USE_DS18x20 #ifdef USE_LMT01 AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO @@ -797,7 +797,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_P9813_CLK), // P9813 CLOCK AGPIO(GPIO_P9813_DAT), // P9813 DATA #else - AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 0), // WS2812 Led string, using RMT on ESP32 + AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 1) -1, // WS2812 Led string, using RMT on ESP32 #endif // NEO_HW_P9813 #endif #ifdef USE_ARILUX_RF @@ -815,15 +815,15 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_SM16716 #ifdef USE_SM2135 AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK - AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT, // SM2135 DATA + AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT -1, // SM2135 DATA #endif // USE_SM2135 #ifdef USE_SM2335 AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK - AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT, // SM2335 DATA + AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT -1, // SM2335 DATA #endif // USE_SM2335 #ifdef USE_BP1658CJ AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK - AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT, // BP1658CJ DATA + AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT -1, // BP1658CJ DATA #endif // USE_BP1658CJ #ifdef USE_BP5758D AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK @@ -857,7 +857,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRSEND) + MAX_IRSEND, // IR remote + AGPIO(GPIO_IRSEND) + MAX_IRSEND -1, // IR remote #if defined(USE_IR_RECEIVE) || defined(USE_IR_REMOTE_FULL) AGPIO(GPIO_IRRECV), // IR receiver #endif @@ -870,8 +870,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding #endif #ifdef USE_SR04 - AGPIO(GPIO_SR04_TRIG) + MAX_SR04, // SR04 Tri/TXgger pin - AGPIO(GPIO_SR04_ECHO) + MAX_SR04, // SR04 Ech/RXo pin + AGPIO(GPIO_SR04_TRIG) + MAX_SR04 -1, // SR04 Tri/TXgger pin + AGPIO(GPIO_SR04_ECHO) + MAX_SR04 -1, // SR04 Ech/RXo pin #endif #ifdef USE_ME007 AGPIO(GPIO_ME007_TRIG), // ME007 Trigger pin (xsns_23_me007.ino) @@ -904,20 +904,20 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power #endif #if defined(USE_I2C) && defined(USE_ADE7880) - AGPIO(GPIO_ADE7880_IRQ) + 2, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) + AGPIO(GPIO_ADE7880_IRQ) + 2 -1, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) #endif #ifdef USE_ADE7953 #if defined(USE_I2C) || defined(USE_SPI) - AGPIO(GPIO_ADE7953_IRQ) + 6, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) + AGPIO(GPIO_ADE7953_IRQ) + 6 -1, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset #ifdef USE_SPI - AGPIO(GPIO_ADE7953_CS) + 2, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) + AGPIO(GPIO_ADE7953_CS) + 2 -1, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) #endif // USE_SPI #endif // USE_I2C or USE_SPI #endif // USE_ADE7953 #ifdef USE_CSE7761 AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) - AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) + AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761 -1, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) #endif #ifdef USE_CSE7766 AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) @@ -972,13 +972,13 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_LE01MR #ifdef ESP32 #ifdef USE_BL0906 - AGPIO(GPIO_BL0906_RX) + MAX_BL0906_RX, // BL0906 Serial interface (Athom EM6) + AGPIO(GPIO_BL0906_RX) + MAX_BL0906_RX -1, // BL0906 Serial interface (Athom EM6) #endif // USE_BL0906 #endif // ESP32 #if defined(USE_BL0940) || defined(USE_BL09XX) AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface - AGPIO(GPIO_BL0942_RX) + MAX_BL0942_RX, // BL0942 Serial interface + AGPIO(GPIO_BL0942_RX) + MAX_BL0942_RX -1, // BL0942 Serial interface #endif #ifdef USE_IEM3000 AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface @@ -1024,7 +1024,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_ZIGBEE AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RST) + 2, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode + AGPIO(GPIO_ZIGBEE_RST) + 2 -1, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode #endif #ifdef USE_MHZ19 AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface @@ -1147,7 +1147,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MGC3130_RESET), #endif #ifdef USE_MAX31855 - AGPIO(GPIO_MAX31855CS) + MAX_MAX31855S, //MAX31855 Serial interface + AGPIO(GPIO_MAX31855CS) + MAX_MAX31855S -1, //MAX31855 Serial interface AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface #endif @@ -1160,7 +1160,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_A4988_STP), // A4988 step pin // folowing are not mandatory AGPIO(GPIO_A4988_ENA), // A4988 enabled pin - AGPIO(GPIO_A4988_MS1) + MAX_A4988_MSS, // A4988 microstep pin1 to pin3 + AGPIO(GPIO_A4988_MS1) + MAX_A4988_MSS -1, // A4988 microstep pin1 to pin3 #endif #ifdef USE_DEEPSLEEP AGPIO(GPIO_DEEPSLEEP), @@ -1203,10 +1203,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control #endif #if defined(USE_VL53L0X) or defined (USE_VL53L1X) - AGPIO(GPIO_VL53LXX_XSHUT1) + VL53LXX_MAX_SENSORS, // When using multiple VL53LXX. + AGPIO(GPIO_VL53LXX_XSHUT1) + VL53LXX_MAX_SENSORS -1, // When using multiple VL53LXX. #endif #ifdef USE_FLOWRATEMETER - AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER, // Flow meter Pin + AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER -1, // Flow meter Pin #endif #ifdef USE_SHIFT595 @@ -1217,7 +1217,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #if defined (ESP32) && defined(USE_DINGTIAN_RELAY) - AGPIO(GPIO_DINGTIAN_CLK) + MAX_DINGTIAN_SHIFT, // Dingtian Relay board - 8,16,24 or 32 relays & inputs + AGPIO(GPIO_DINGTIAN_CLK) + MAX_DINGTIAN_SHIFT -1, // Dingtian Relay board - 8,16,24 or 32 relays & inputs AGPIO(GPIO_DINGTIAN_SDI), AGPIO(GPIO_DINGTIAN_Q7), AGPIO(GPIO_DINGTIAN_PL), @@ -1226,7 +1226,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #ifdef USE_MAGIC_SWITCH - AGPIO(GPIO_MAGIC_SWITCH) + MAX_MAGIC_SWITCH_MODES, + AGPIO(GPIO_MAGIC_SWITCH) + MAX_MAGIC_SWITCH_MODES -1, #endif #ifdef USE_PIPSOLAR // xdrv_92_pipsolar.ino @@ -1240,7 +1240,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef ESP32 #if CONFIG_IDF_TARGET_ESP32 - AGPIO(GPIO_HALLEFFECT) + 2, // Hall effect sensor connected to GPIO36 and 39 + AGPIO(GPIO_HALLEFFECT) + 2 -1, // Hall effect sensor connected to GPIO36 and 39 #endif // CONFIG_IDF_TARGET_ESP32 #ifdef USE_WEBCAM AGPIO(GPIO_WEBCAM_PWDN), @@ -1248,12 +1248,12 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_WEBCAM_XCLK), AGPIO(GPIO_WEBCAM_SIOD), AGPIO(GPIO_WEBCAM_SIOC), - AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA, + AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA -1, AGPIO(GPIO_WEBCAM_VSYNC), AGPIO(GPIO_WEBCAM_HREF), AGPIO(GPIO_WEBCAM_PCLK), AGPIO(GPIO_WEBCAM_PSCLK), - AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD, + AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD -1, AGPIO(GPIO_WEBCAM_PSRCS), #endif // USE_WEBCAM #ifdef USE_ETHERNET @@ -1264,25 +1264,25 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_BIOPDU AGPIO(GPIO_BIOPDU_PZEM0XX_TX), // Biomine BioPDU pins AGPIO(GPIO_BIOPDU_PZEM016_RX), - AGPIO(GPIO_BIOPDU_BIT) + 3, + AGPIO(GPIO_BIOPDU_BIT) + 3 -1, #endif /*-------------------------------------------------------------------------------------------*\ * ESP32 multiple Analog / Digital converter inputs \*-------------------------------------------------------------------------------------------*/ - AGPIO(GPIO_ADC_INPUT) + MAX_ADCS, // Analog inputs - AGPIO(GPIO_ADC_TEMP) + MAX_ADCS, // Thermistor - AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS, // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button - AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS, - AGPIO(GPIO_ADC_RANGE) + MAX_ADCS, // Range - AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS, // Current - AGPIO(GPIO_ADC_JOY) + MAX_ADCS, // Joystick - AGPIO(GPIO_ADC_PH) + MAX_ADCS, // Analog PH Sensor - AGPIO(GPIO_ADC_MQ) + MAX_ADCS, // Analog MQ Sensor - AGPIO(GPIO_ADC_VOLTAGE) + MAX_ADCS, // Voltage - AGPIO(GPIO_ADC_CURRENT) + MAX_ADCS, // Current + AGPIO(GPIO_ADC_INPUT) + MAX_ADCS -1, // Analog inputs + AGPIO(GPIO_ADC_TEMP) + MAX_ADCS -1, // Thermistor + AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS -1, // Light sensor + AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS -1, // Button + AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS -1, + AGPIO(GPIO_ADC_RANGE) + MAX_ADCS -1, // Range + AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS -1, // Current + AGPIO(GPIO_ADC_JOY) + MAX_ADCS -1, // Joystick + AGPIO(GPIO_ADC_PH) + MAX_ADCS -1, // Analog PH Sensor + AGPIO(GPIO_ADC_MQ) + MAX_ADCS -1, // Analog MQ Sensor + AGPIO(GPIO_ADC_VOLTAGE) + MAX_ADCS -1, // Voltage + AGPIO(GPIO_ADC_CURRENT) + MAX_ADCS -1, // Current #endif // ESP32 }; @@ -1296,8 +1296,8 @@ const uint16_t kAdcNiceList[] PROGMEM = { AGPIO(GPIO_ADC_INPUT), // Analog inputs AGPIO(GPIO_ADC_TEMP), // Thermistor AGPIO(GPIO_ADC_LIGHT), // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button - AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS, + AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS -1, // Button + AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS -1, AGPIO(GPIO_ADC_RANGE), // Range AGPIO(GPIO_ADC_CT_POWER), // Current AGPIO(GPIO_ADC_JOY), // Joystick diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index facaa1471..dbcab5b1d 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -679,24 +679,24 @@ typedef struct { uint16_t light_wakeup; // 4A6 uint8_t knx_CB_registered; // 4A8 Number of Group Address to write uint8_t switchmode[MAX_SWITCHES_SET]; // 4A9 - uint8_t global_sensor_index[3]; // 4C5 - uint16_t dns_timeout; // 4C8 - uint8_t ds3502_state[MAX_DS3502]; // 4CA - uint16_t influxdb_port; // 4CE - power_t interlock[MAX_INTERLOCKS_SET]; // 4D0 MAX_INTERLOCKS = MAX_RELAYS / 2 - int8_t shutter_tilt_config[5][MAX_SHUTTERS]; //508 - int8_t shutter_tilt_pos[MAX_SHUTTERS]; //51C - uint16_t influxdb_period; // 520 - uint16_t rf_duplicate_time; // 522 - int32_t weight_absconv_a; // 524 - int32_t weight_absconv_b; // 528 - uint16_t mqtt_keepalive; // 52C - uint16_t mqtt_socket_timeout; // 52E - uint8_t mqtt_wifi_timeout; // 530 - uint8_t ina219_mode; // 531 - uint8_t weight_precision; // 532 ex_pulse_timer free since 11.0.0.3 + uint8_t global_sensor_index[3]; // 4C9 4C5 - Moved up by 4 bytes in v14.3.0.7 + uint16_t dns_timeout; // 4CC 4C8 + uint8_t ds3502_state[MAX_DS3502]; // 4CE 4CA + uint16_t influxdb_port; // 4D2 4CE + power_t interlock[MAX_INTERLOCKS_SET]; // 4D4 4D0 MAX_INTERLOCKS = MAX_RELAYS / 2 + int8_t shutter_tilt_config[5][MAX_SHUTTERS]; // 514 508 - Moved up 12 bytes in v14.3.0.7 + int8_t shutter_tilt_pos[MAX_SHUTTERS]; // 528 51C + uint16_t influxdb_period; // 52C 520 + uint16_t rf_duplicate_time; // 52E 522 + int32_t weight_absconv_a; // 530 524 + int32_t weight_absconv_b; // 534 528 + uint16_t mqtt_keepalive; // 538 52C + uint16_t mqtt_socket_timeout; // 53A 52E + uint8_t mqtt_wifi_timeout; // 53C 530 + uint8_t ina219_mode; // 53D 531 + uint8_t weight_precision; // 53E 532 - uint8_t free_533[13]; // 533 + uint8_t free_53F; // 53F uint16_t tcp_baudrate; // 540 uint16_t button_debounce; // 542 diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index c7f0d2d3f..8e6cd8138 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E030006; // 14.3.0.6 +const uint32_t TASMOTA_VERSION = 0x0E030007; // 14.3.0.7 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index abfb85484..941f27968 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -1855,6 +1855,16 @@ void SettingsDelta(void) { char scolor[10]; WebHexCode(COL_BUTTON_OFF, GetTextIndexed(scolor, sizeof(scolor), COL_BUTTON_OFF, kWebColors)); } + if (Settings->version < 0x0E030007) { // 14.3.0.7 + memmove_P((uint8_t*)&Settings->shutter_tilt_config, (uint8_t*)&Settings->shutter_tilt_config - 12, 0x2B); + for (uint32_t i = 14; i < MAX_INTERLOCKS_SET; i++) { + Settings->interlock[i] = 0; + } + memmove_P((uint8_t*)&Settings->global_sensor_index, (uint8_t*)&Settings->global_sensor_index - 4, 0x43); + for (uint32_t i = 28; i < MAX_SWITCHES_SET; i++) { + Settings->switchmode[i] = SWITCH_MODE; + } + } Settings->version = TASMOTA_VERSION; SettingsSave(1); diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index d385ec0ac..4c96ad7aa 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -832,6 +832,7 @@ int32_t UpdateDevicesPresent(int32_t change) { else if (devices_present >= POWER_SIZE) { // Support up to uint32_t as bitmask difference = devices_present - POWER_SIZE; devices_present = POWER_SIZE; + AddLog(LOG_LEVEL_DEBUG, PSTR("APP: Max number of devices reached")); } TasmotaGlobal.devices_present = devices_present; return difference; diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 559e796c6..e1ed6a7da 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -2882,11 +2882,11 @@ void CmndTouchCal(void) { if (XdrvMailbox.payload == 0) { TouchButton.calibration = 0; } - else if (XdrvMailbox.payload < MAX_KEYS + 1) { + else if (XdrvMailbox.payload < MAX_KEYS) { TouchButton.calibration = bitSet(TouchButton.calibration, XdrvMailbox.payload); } else if (XdrvMailbox.payload == 255) { - TouchButton.calibration = 0x0FFFFFFF; // All MAX_KEYS pins + TouchButton.calibration = 0xFFFFFFFF; // All MAX_KEYS pins } } ResponseCmndNumber(TouchButton.calibration); From 682129381983a3f1e1c9cb0de20a017a0704bf06 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 17 Nov 2024 11:30:55 +0100 Subject: [PATCH 137/205] Revert "Bump version v14.3.0.7" This reverts commit 14c0a42203d9664bd4aa4054ace500755d240e99. --- CHANGELOG.md | 15 +- RELEASENOTES.md | 4 +- .../HTTP_SCRIPT_MODULE_TEMPLATE.h | 24 +-- .../HTTP_SCRIPT_MODULE_TEMPLATE.h | 2 +- tasmota/include/tasmota.h | 13 +- tasmota/include/tasmota_template.h | 174 +++++++++--------- tasmota/include/tasmota_types.h | 34 ++-- tasmota/include/tasmota_version.h | 2 +- tasmota/tasmota_support/settings.ino | 10 - tasmota/tasmota_support/support.ino | 1 - tasmota/tasmota_support/support_command.ino | 4 +- 11 files changed, 132 insertions(+), 151 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcef330d4..d776ec2b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,27 +3,20 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.3.0.7] +## [14.3.0.6] ### Added +- Add command ``WebColor20`` to control color of Button when Off ### Breaking Changed -### Fixed - -### Removed - ### Changed -- ESP32 max number of supported switches/buttons/relays from 28 to 32 -- ESP32 max number of interlocks from 14 to 16 - -## [14.3.0.6] 20241116 -### Added -- Add command ``WebColor20`` to control color of Button when Off ### Fixed - Matter provisioning with matter.js controller (#22470) - Prevent crashing when `display.ini` is missing end `#` (#22471) +### Removed + ## [14.3.0.5] 20241111 ### Added - ESP32 MI32 legacy add config operations (#22458) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ed100cf8d..eac5e949c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -114,7 +114,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.3.0.7 +## Changelog v14.3.0.6 ### Added - Add command ``WebColor20`` to control color of Button when Off - DALI support for short addresses (gear) and groups @@ -157,8 +157,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default - Shutter optimized behavior to publish shutter data with sensor request [#22353](https://github.com/arendst/Tasmota/issues/22353) -- ESP32 max number of supported switches/buttons/relays from 28 to 32 -- ESP32 max number of interlocks from 14 to 16 - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed diff --git a/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h b/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h index 99c40b1ac..e7f059b0b 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h @@ -2,7 +2,7 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 589; +const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 602; const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\xD4\x2B\xC7\x83\x02\xF8\x3A\xDC\xE4\x1B\x3B\xBA\x75\x1A\x8E\xF1" "\xED\x33\xBF\xAC\x3E\x09\x81\x8B\x1A\xFA\x8E\x81\xFD\xDD\x32\x61\x31\xAF\xA8\xEE" "\x9F\x78\x32\xB7\x38\xFB\x3B\xC7\x8C\x3A\x53\x36\x51\x07\x9D\x4F\xA8\xF9\xA7\x83" @@ -15,16 +15,16 @@ const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\ "\x0C\x3A\x7D\x8D\xC3\x36\x08\x3B\x70\x24\xE0\x87\x78\xF0\x7B\x82\x3E\x0A\x04\xAC" "\xC8\xE3\x3C\x16\x9E\x81\x1E\x34\xED\x9D\xB3\xBC\x7B\x43\x3E\x0A\xF1\xEF\x69\xEF" "\x82\x17\x2A\x01\xE7\x8D\x30\x77\x6C\xF8\x7C\x0C\xEF\x1E\xD1\xC0\x89\x50\xE3\x70" - "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x23\x64\x47\xC1" - "\xC0\x85\x91\xB3\xBB\xA7\x6C\xE4\x3A\x8A\x8E\xF1\xE0\xF7\x31\xC7\x74\xFB\x14\x7D" - "\x9D\xB1\xE3\xBC\x74\x33\xB0\x85\xB3\xE0\xB3\xB6\x72\x1E\x0A\x8E\x9E\xA3\x20\x99" - "\xD0\xCF\x7D\xA3\xB4\x2D\xA3\x23\xE1\xDD\x1C\x7E\x1C\x67\x78\xED\x1F\x67\xD9\xE6" - "\x7D\x90\xAD\x10\x47\xC7\xD8\x23\x71\x49\xE3\x43\xBB\xE3\xA8\x78\x10\xF8\xFE\xCF" - "\x1D\x3E\xC6\x05\x61\xB3\xBA\x76\x1E\xE3\x94\x76\x10\xF1\xD4\x7B\x0F\x40\x41\xE0" - "\xF9\x02\x0E\x7A\x7D\x9E\xC3\xBC\x08\xD7\x4E\x59\xD8\x43\xC7\x51\xEC\x3D\x0E\xC0" - "\x41\xBC\x7E\x1E\xC3\xBC\x78\x63\x8E\xE9\xF6\x3C\x7D\x9D\xB1\xE3\xBC\x74\xDE\xE7" - "\xF2\x14\x54\x43\x48\x23\xE6\x02\x35\x20\x41\xC8\x4E\xE8\xF1\xE8\x71\x23\xBC\x76" - "\x88\x10\xF9\x10\x3C\xFC\x78\xD3\x2A\x01\x83\x40\xF6\x82\x17\x26\x47\x83\xDC\x7B" - "\x8D"; + "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x21\x64\x47\x21" + "\xE0\xB4\xF4\x3E\x0E\x04\x2C\x8D\x9D\xD3\xBB\xA7\xA1\xC8\xCE\xF1\xDA\x3B\xA7\xD9" + "\xDC\x3E\xCE\xD9\x69\xDE\x3C\xF4\xEA\xA3\xBC\x78\x3D\xCC\x71\xDD\x3E\xC5\x1F\x67" + "\x6C\x78\xEF\x1D\x0C\xEC\x21\x6C\xF8\x2C\xED\x9C\x87\x82\xA3\xA7\xA8\xC8\x26\x74" + "\x33\xDF\x68\xED\x0B\x68\xC8\xF8\x77\x47\x1F\x87\x19\xDE\x3B\x47\xD9\xF6\x79\x9F" + "\x64\x2B\x44\x11\xF1\xF6\x08\xDC\x58\xF8\xD0\xEE\xF8\xEA\x1E\x04\x3E\x42\xF3\xC7" + "\x4F\xB1\x81\x58\x6C\xEE\x9D\x87\xB8\xE5\x1D\x84\x3C\x75\x1E\xC3\xD0\x10\x78\x4B" + "\x40\x83\x9E\x9F\x67\xB0\xEF\x02\x35\xD3\x96\x76\x10\xF1\xD4\x7B\x0F\x43\xB0\x10" + "\x6F\x1F\x87\xB0\xEF\x1E\x18\xE3\xBA\x7D\x8F\x1F\x67\x6C\x78\xEF\x1D\x37\xB9\xFC" + "\x85\x15\x10\xD2\x08\xF9\x80\x8D\x48\x10\x72\x13\xBA\x3C\x7A\x1C\x48\xEF\x1D\xA2" + "\x04\x3E\x47\x4F\x3F\x1E\x34\xC0\x20\xD0\x3D\xA0\x85\xC9\xF9\xE0\xF7\x1E\xE3"; #define HTTP_SCRIPT_MODULE_TEMPLATE Decompress(HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED,HTTP_SCRIPT_MODULE_TEMPLATE_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h b/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h index 0fcd77c51..fd52afcc0 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h @@ -12,7 +12,7 @@ const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM = "l=hs.length;" // Find max indexes for s "for(i=0;i>=5;" // Add options - "for(i=0;i<=b;i++){ce(i+1,t);}" // Add index 1 to 32 + "for(i=1;i<=b;i++){ce((i<10)?(' '+i):i,t);}" "eb('h'+g).value=u+1;" // Set selected value "t.style.visibility=(b>0)?'':'hidden';" "}" diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index 81ce401f6..ca775b88e 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -38,6 +38,7 @@ const uint32_t POWER_SIZE = 32; // Power (relay) bit count * Constants \*********************************************************************************************/ +// Why 28? Because in addition to relays there may be lights and uint32_t bitmap can hold up to 32 devices #ifdef ESP8266 const uint8_t MAX_RELAYS = 8; // Max number of relays selectable on GPIO const uint8_t MAX_INTERLOCKS = 4; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) @@ -45,17 +46,17 @@ const uint8_t MAX_SWITCHES = 8; // Max number of switches selectable const uint8_t MAX_KEYS = 8; // Max number of keys or buttons selectable on GPIO #endif // ESP8266 #ifdef ESP32 -const uint8_t MAX_RELAYS = 32; // Max number of relays selectable on GPIO -const uint8_t MAX_INTERLOCKS = 16; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) -const uint8_t MAX_SWITCHES = 32; // Max number of switches selectable on GPIO -const uint8_t MAX_KEYS = 32; // Max number of keys or buttons selectable on GPIO +const uint8_t MAX_RELAYS = 28; // Max number of relays selectable on GPIO +const uint8_t MAX_INTERLOCKS = 14; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) +const uint8_t MAX_SWITCHES = 28; // Max number of switches selectable on GPIO +const uint8_t MAX_KEYS = 28; // Max number of keys or buttons selectable on GPIO #endif // ESP32 const uint8_t MAX_RELAYS_SET = 32; // Max number of relays const uint8_t MAX_KEYS_SET = 32; // Max number of keys // Changes to the following MAX_ defines will impact settings layout -const uint8_t MAX_INTERLOCKS_SET = 16; // Max number of interlock groups (MAX_RELAYS_SET / 2) -const uint8_t MAX_SWITCHES_SET = 32; // Max number of switches +const uint8_t MAX_INTERLOCKS_SET = 14; // Max number of interlock groups (MAX_RELAYS_SET / 2) +const uint8_t MAX_SWITCHES_SET = 28; // Max number of switches const uint8_t MAX_LEDS = 4; // Max number of leds const uint8_t MAX_PWMS_LEGACY = 5; // Max number of PWM channels in first settings block - Legacy limit for ESP8266, but extended for ESP32 (see below) #ifdef ESP32 // Max number of PWM channels (total including extended) - ESP32 only diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index f570f8894..d4c324cfb 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -509,7 +509,7 @@ const char kSensorNamesFixed[] PROGMEM = D_SENSOR_USER; // Max number of GPIOs -#define MAX_I2C 1 // Display no index if one bus +#define MAX_I2C 0 // Display no index if one bus #ifdef USE_I2C_BUS2 #undef MAX_I2C #define MAX_I2C 2 @@ -533,46 +533,46 @@ const char kSensorNamesFixed[] PROGMEM = const uint16_t kGpioNiceList[] PROGMEM = { GPIO_NONE, // Not used - AGPIO(GPIO_OPTION_A) + MAX_OPTIONS_A -1, // Device specific options + AGPIO(GPIO_OPTION_A) + MAX_OPTIONS_A, // Device specific options #ifdef ESP32 - AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E -1, // Device module emulation + AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E, // Device module emulation #endif - AGPIO(GPIO_KEY1) + MAX_KEYS -1, // Buttons - AGPIO(GPIO_KEY1_NP) + MAX_KEYS -1, + AGPIO(GPIO_KEY1) + MAX_KEYS, // Buttons + AGPIO(GPIO_KEY1_NP) + MAX_KEYS, #ifdef ESP32 - AGPIO(GPIO_KEY1_PD) + MAX_KEYS -1, + AGPIO(GPIO_KEY1_PD) + MAX_KEYS, #endif - AGPIO(GPIO_KEY1_INV) + MAX_KEYS -1, - AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS -1, + AGPIO(GPIO_KEY1_INV) + MAX_KEYS, + AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS, #ifdef ESP32 - AGPIO(GPIO_KEY1_INV_PD) + MAX_KEYS -1, + AGPIO(GPIO_KEY1_INV_PD) + MAX_KEYS, #if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2) - AGPIO(GPIO_KEY1_TC) + MAX_KEYS -1, // Touch button + AGPIO(GPIO_KEY1_TC) + MAX_KEYS, // Touch button #endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 #endif - AGPIO(GPIO_SWT1) + MAX_SWITCHES -1, // User connected external switches - AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES -1, + AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches + AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES, #ifdef ESP32 - AGPIO(GPIO_SWT1_PD) + MAX_SWITCHES -1, + AGPIO(GPIO_SWT1_PD) + MAX_SWITCHES, #endif #ifdef ROTARY_V1 - AGPIO(GPIO_ROT1A) + MAX_ROTARIES -1, // Rotary A Pin - AGPIO(GPIO_ROT1B) + MAX_ROTARIES -1, // Rotary B Pin - AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES -1, // Rotary A Pin No Pullup - AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES -1, // Rotary B Pin No Pullup + AGPIO(GPIO_ROT1A) + MAX_ROTARIES, // Rotary A Pin + AGPIO(GPIO_ROT1B) + MAX_ROTARIES, // Rotary B Pin + AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES, // Rotary A Pin No Pullup + AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES, // Rotary B Pin No Pullup #endif - AGPIO(GPIO_REL1) + MAX_RELAYS -1, // Relays - AGPIO(GPIO_REL1_INV) + MAX_RELAYS -1, - AGPIO(GPIO_REL1_BI) + MAX_RELAYS -1, // Bistable (Latching) two coil relays - AGPIO(GPIO_REL1_BI_INV) + MAX_RELAYS -1, - AGPIO(GPIO_LED1) + MAX_LEDS -1, // Leds - AGPIO(GPIO_LED1_INV) + MAX_LEDS -1, + AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays + AGPIO(GPIO_REL1_INV) + MAX_RELAYS, + AGPIO(GPIO_REL1_BI) + MAX_RELAYS, // Bistable (Latching) two coil relays + AGPIO(GPIO_REL1_BI_INV) + MAX_RELAYS, + AGPIO(GPIO_LED1) + MAX_LEDS, // Leds + AGPIO(GPIO_LED1_INV) + MAX_LEDS, #ifdef USE_COUNTER - AGPIO(GPIO_CNTR1) + MAX_COUNTERS -1, // Counters - AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS -1, + AGPIO(GPIO_CNTR1) + MAX_COUNTERS, // Counters + AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS, #endif - AGPIO(GPIO_PWM1) + MAX_PWMS -1, // RGB Red or C Cold White - AGPIO(GPIO_PWM1_INV) + MAX_PWMS -1, // or extended PWM for ESP32 + AGPIO(GPIO_PWM1) + MAX_PWMS, // RGB Red or C Cold White + AGPIO(GPIO_PWM1_INV) + MAX_PWMS, // or extended PWM for ESP32 #ifdef USE_BUZZER AGPIO(GPIO_BUZZER), // Buzzer AGPIO(GPIO_BUZZER_INV), // Inverted buzzer @@ -580,8 +580,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_LEDLNK), // Link led AGPIO(GPIO_LEDLNK_INV), // Inverted link led #ifdef USE_BERRY - AGPIO(GPIO_INPUT) + MAX_SWITCHES -1, // Pure digital input to be read via Berry - AGPIO(GPIO_INTERRUPT) + MAX_SWITCHES -1, // Interrupt pins to be catched by Berry + AGPIO(GPIO_INPUT) + MAX_SWITCHES, // Pure digital input to be read via Berry + AGPIO(GPIO_INTERRUPT) + MAX_SWITCHES, // Interrupt pins to be catched by Berry #endif AGPIO(GPIO_OUTPUT_HI), // Fixed output high AGPIO(GPIO_OUTPUT_LO), // Fixed output low @@ -601,32 +601,32 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #ifdef USE_I2C - AGPIO(GPIO_I2C_SCL) + MAX_I2C -1, // I2C SCL - AGPIO(GPIO_I2C_SDA) + MAX_I2C -1, // I2C SDA + AGPIO(GPIO_I2C_SCL) + MAX_I2C, // I2C SCL + AGPIO(GPIO_I2C_SDA) + MAX_I2C, // I2C SDA #ifdef USE_PCF8574 AGPIO(GPIO_PCF8574_INT), // PCF8574 Interrupt #endif // USE_PCF8574 #ifdef USE_I2C_SERIAL - AGPIO(GPIO_I2C_SER_TX) + MAX_I2C -1, // I2C via Serial TX - AGPIO(GPIO_I2C_SER_RX) + MAX_I2C -1, // I2C via Serial RX + AGPIO(GPIO_I2C_SER_TX) + MAX_I2C, // I2C via Serial TX + AGPIO(GPIO_I2C_SER_RX) + MAX_I2C, // I2C via Serial RX #endif // USE_I2C_SERIAL #endif #if defined(USE_I2S_AUDIO) || defined (USE_I2S) - AGPIO(GPIO_I2S_MCLK) + MAX_I2S -1, // I2S master clock - AGPIO(GPIO_I2S_BCLK) + MAX_I2S -1, // I2S bit clock - AGPIO(GPIO_I2S_DOUT) + MAX_I2S -1, // I2S Out Data - AGPIO(GPIO_I2S_DAC) + 2 -1, // I2S DAC Output - AGPIO(GPIO_I2S_WS) + MAX_I2S -1, // I2S word select - AGPIO(GPIO_I2S_DIN) + MAX_I2S -1, // I2S IN Data + AGPIO(GPIO_I2S_MCLK) + MAX_I2S, // I2S master clock + AGPIO(GPIO_I2S_BCLK) + MAX_I2S, // I2S bit clock + AGPIO(GPIO_I2S_DOUT) + MAX_I2S, // I2S Out Data + AGPIO(GPIO_I2S_DAC) + 2, // I2S DAC Output + AGPIO(GPIO_I2S_WS) + MAX_I2S, // I2S word select + AGPIO(GPIO_I2S_DIN) + MAX_I2S, // I2S IN Data #endif #ifdef USE_SPI - AGPIO(GPIO_SPI_MISO) + MAX_SPI -1, // SPI MISO - AGPIO(GPIO_SPI_MOSI) + MAX_SPI -1, // SPI MOSI - AGPIO(GPIO_SPI_CLK) + MAX_SPI -1, // SPI Clk - AGPIO(GPIO_SPI_CS) + MAX_SPI -1, // SPI Chip Select - AGPIO(GPIO_SPI_DC) + MAX_SPI -1, // SPI Data Direction + AGPIO(GPIO_SPI_MISO) + MAX_SPI, // SPI MISO + AGPIO(GPIO_SPI_MOSI) + MAX_SPI, // SPI MOSI + AGPIO(GPIO_SPI_CLK) + MAX_SPI, // SPI Clk + AGPIO(GPIO_SPI_CS) + MAX_SPI, // SPI Chip Select + AGPIO(GPIO_SPI_DC) + MAX_SPI, // SPI Data Direction #ifdef USE_NRF24 AGPIO(GPIO_NRF24_CS), AGPIO(GPIO_NRF24_DC), @@ -642,7 +642,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MCP2515_CS), #endif // USE_MCP2515 #ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23SXX_CS) + MAX_MCP23XXX -1, + AGPIO(GPIO_MCP23SXX_CS) + MAX_MCP23XXX, #endif // USE_MCP23XXX_DRV #ifdef USE_SPI_LORA AGPIO(GPIO_LORA_CS), @@ -754,11 +754,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_DISPLAY_TM1621_SONOFF #ifdef USE_MAX31865 - AGPIO(GPIO_SSPI_MAX31865_CS1) + MAX_MAX31865S -1, + AGPIO(GPIO_SSPI_MAX31865_CS1) + MAX_MAX31865S, #endif #ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23XXX_INT) + MAX_MCP23XXX -1, + AGPIO(GPIO_MCP23XXX_INT) + MAX_MCP23XXX, #endif #ifdef USE_HDMI_CEC @@ -780,8 +780,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 #endif #ifdef USE_DS18x20 - AGPIO(GPIO_DSB) + MAX_DSB -1, // Single wire DS18B20 or DS18S20 - AGPIO(GPIO_DSB_OUT) + MAX_DSB -1, // Pseudo Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20 #endif // USE_DS18x20 #ifdef USE_LMT01 AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO @@ -797,7 +797,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_P9813_CLK), // P9813 CLOCK AGPIO(GPIO_P9813_DAT), // P9813 DATA #else - AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 1) -1, // WS2812 Led string, using RMT on ESP32 + AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 0), // WS2812 Led string, using RMT on ESP32 #endif // NEO_HW_P9813 #endif #ifdef USE_ARILUX_RF @@ -815,15 +815,15 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_SM16716 #ifdef USE_SM2135 AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK - AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT -1, // SM2135 DATA + AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT, // SM2135 DATA #endif // USE_SM2135 #ifdef USE_SM2335 AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK - AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT -1, // SM2335 DATA + AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT, // SM2335 DATA #endif // USE_SM2335 #ifdef USE_BP1658CJ AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK - AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT -1, // BP1658CJ DATA + AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT, // BP1658CJ DATA #endif // USE_BP1658CJ #ifdef USE_BP5758D AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK @@ -857,7 +857,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRSEND) + MAX_IRSEND -1, // IR remote + AGPIO(GPIO_IRSEND) + MAX_IRSEND, // IR remote #if defined(USE_IR_RECEIVE) || defined(USE_IR_REMOTE_FULL) AGPIO(GPIO_IRRECV), // IR receiver #endif @@ -870,8 +870,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding #endif #ifdef USE_SR04 - AGPIO(GPIO_SR04_TRIG) + MAX_SR04 -1, // SR04 Tri/TXgger pin - AGPIO(GPIO_SR04_ECHO) + MAX_SR04 -1, // SR04 Ech/RXo pin + AGPIO(GPIO_SR04_TRIG) + MAX_SR04, // SR04 Tri/TXgger pin + AGPIO(GPIO_SR04_ECHO) + MAX_SR04, // SR04 Ech/RXo pin #endif #ifdef USE_ME007 AGPIO(GPIO_ME007_TRIG), // ME007 Trigger pin (xsns_23_me007.ino) @@ -904,20 +904,20 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power #endif #if defined(USE_I2C) && defined(USE_ADE7880) - AGPIO(GPIO_ADE7880_IRQ) + 2 -1, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) + AGPIO(GPIO_ADE7880_IRQ) + 2, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) #endif #ifdef USE_ADE7953 #if defined(USE_I2C) || defined(USE_SPI) - AGPIO(GPIO_ADE7953_IRQ) + 6 -1, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) + AGPIO(GPIO_ADE7953_IRQ) + 6, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset #ifdef USE_SPI - AGPIO(GPIO_ADE7953_CS) + 2 -1, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) + AGPIO(GPIO_ADE7953_CS) + 2, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) #endif // USE_SPI #endif // USE_I2C or USE_SPI #endif // USE_ADE7953 #ifdef USE_CSE7761 AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) - AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761 -1, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) + AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) #endif #ifdef USE_CSE7766 AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) @@ -972,13 +972,13 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_LE01MR #ifdef ESP32 #ifdef USE_BL0906 - AGPIO(GPIO_BL0906_RX) + MAX_BL0906_RX -1, // BL0906 Serial interface (Athom EM6) + AGPIO(GPIO_BL0906_RX) + MAX_BL0906_RX, // BL0906 Serial interface (Athom EM6) #endif // USE_BL0906 #endif // ESP32 #if defined(USE_BL0940) || defined(USE_BL09XX) AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface - AGPIO(GPIO_BL0942_RX) + MAX_BL0942_RX -1, // BL0942 Serial interface + AGPIO(GPIO_BL0942_RX) + MAX_BL0942_RX, // BL0942 Serial interface #endif #ifdef USE_IEM3000 AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface @@ -1024,7 +1024,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_ZIGBEE AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RST) + 2 -1, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode + AGPIO(GPIO_ZIGBEE_RST) + 2, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode #endif #ifdef USE_MHZ19 AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface @@ -1147,7 +1147,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MGC3130_RESET), #endif #ifdef USE_MAX31855 - AGPIO(GPIO_MAX31855CS) + MAX_MAX31855S -1, //MAX31855 Serial interface + AGPIO(GPIO_MAX31855CS) + MAX_MAX31855S, //MAX31855 Serial interface AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface #endif @@ -1160,7 +1160,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_A4988_STP), // A4988 step pin // folowing are not mandatory AGPIO(GPIO_A4988_ENA), // A4988 enabled pin - AGPIO(GPIO_A4988_MS1) + MAX_A4988_MSS -1, // A4988 microstep pin1 to pin3 + AGPIO(GPIO_A4988_MS1) + MAX_A4988_MSS, // A4988 microstep pin1 to pin3 #endif #ifdef USE_DEEPSLEEP AGPIO(GPIO_DEEPSLEEP), @@ -1203,10 +1203,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control #endif #if defined(USE_VL53L0X) or defined (USE_VL53L1X) - AGPIO(GPIO_VL53LXX_XSHUT1) + VL53LXX_MAX_SENSORS -1, // When using multiple VL53LXX. + AGPIO(GPIO_VL53LXX_XSHUT1) + VL53LXX_MAX_SENSORS, // When using multiple VL53LXX. #endif #ifdef USE_FLOWRATEMETER - AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER -1, // Flow meter Pin + AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER, // Flow meter Pin #endif #ifdef USE_SHIFT595 @@ -1217,7 +1217,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #if defined (ESP32) && defined(USE_DINGTIAN_RELAY) - AGPIO(GPIO_DINGTIAN_CLK) + MAX_DINGTIAN_SHIFT -1, // Dingtian Relay board - 8,16,24 or 32 relays & inputs + AGPIO(GPIO_DINGTIAN_CLK) + MAX_DINGTIAN_SHIFT, // Dingtian Relay board - 8,16,24 or 32 relays & inputs AGPIO(GPIO_DINGTIAN_SDI), AGPIO(GPIO_DINGTIAN_Q7), AGPIO(GPIO_DINGTIAN_PL), @@ -1226,7 +1226,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #ifdef USE_MAGIC_SWITCH - AGPIO(GPIO_MAGIC_SWITCH) + MAX_MAGIC_SWITCH_MODES -1, + AGPIO(GPIO_MAGIC_SWITCH) + MAX_MAGIC_SWITCH_MODES, #endif #ifdef USE_PIPSOLAR // xdrv_92_pipsolar.ino @@ -1240,7 +1240,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef ESP32 #if CONFIG_IDF_TARGET_ESP32 - AGPIO(GPIO_HALLEFFECT) + 2 -1, // Hall effect sensor connected to GPIO36 and 39 + AGPIO(GPIO_HALLEFFECT) + 2, // Hall effect sensor connected to GPIO36 and 39 #endif // CONFIG_IDF_TARGET_ESP32 #ifdef USE_WEBCAM AGPIO(GPIO_WEBCAM_PWDN), @@ -1248,12 +1248,12 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_WEBCAM_XCLK), AGPIO(GPIO_WEBCAM_SIOD), AGPIO(GPIO_WEBCAM_SIOC), - AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA -1, + AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA, AGPIO(GPIO_WEBCAM_VSYNC), AGPIO(GPIO_WEBCAM_HREF), AGPIO(GPIO_WEBCAM_PCLK), AGPIO(GPIO_WEBCAM_PSCLK), - AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD -1, + AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD, AGPIO(GPIO_WEBCAM_PSRCS), #endif // USE_WEBCAM #ifdef USE_ETHERNET @@ -1264,25 +1264,25 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_BIOPDU AGPIO(GPIO_BIOPDU_PZEM0XX_TX), // Biomine BioPDU pins AGPIO(GPIO_BIOPDU_PZEM016_RX), - AGPIO(GPIO_BIOPDU_BIT) + 3 -1, + AGPIO(GPIO_BIOPDU_BIT) + 3, #endif /*-------------------------------------------------------------------------------------------*\ * ESP32 multiple Analog / Digital converter inputs \*-------------------------------------------------------------------------------------------*/ - AGPIO(GPIO_ADC_INPUT) + MAX_ADCS -1, // Analog inputs - AGPIO(GPIO_ADC_TEMP) + MAX_ADCS -1, // Thermistor - AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS -1, // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS -1, // Button - AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS -1, - AGPIO(GPIO_ADC_RANGE) + MAX_ADCS -1, // Range - AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS -1, // Current - AGPIO(GPIO_ADC_JOY) + MAX_ADCS -1, // Joystick - AGPIO(GPIO_ADC_PH) + MAX_ADCS -1, // Analog PH Sensor - AGPIO(GPIO_ADC_MQ) + MAX_ADCS -1, // Analog MQ Sensor - AGPIO(GPIO_ADC_VOLTAGE) + MAX_ADCS -1, // Voltage - AGPIO(GPIO_ADC_CURRENT) + MAX_ADCS -1, // Current + AGPIO(GPIO_ADC_INPUT) + MAX_ADCS, // Analog inputs + AGPIO(GPIO_ADC_TEMP) + MAX_ADCS, // Thermistor + AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS, // Light sensor + AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button + AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS, + AGPIO(GPIO_ADC_RANGE) + MAX_ADCS, // Range + AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS, // Current + AGPIO(GPIO_ADC_JOY) + MAX_ADCS, // Joystick + AGPIO(GPIO_ADC_PH) + MAX_ADCS, // Analog PH Sensor + AGPIO(GPIO_ADC_MQ) + MAX_ADCS, // Analog MQ Sensor + AGPIO(GPIO_ADC_VOLTAGE) + MAX_ADCS, // Voltage + AGPIO(GPIO_ADC_CURRENT) + MAX_ADCS, // Current #endif // ESP32 }; @@ -1296,8 +1296,8 @@ const uint16_t kAdcNiceList[] PROGMEM = { AGPIO(GPIO_ADC_INPUT), // Analog inputs AGPIO(GPIO_ADC_TEMP), // Thermistor AGPIO(GPIO_ADC_LIGHT), // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS -1, // Button - AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS -1, + AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button + AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS, AGPIO(GPIO_ADC_RANGE), // Range AGPIO(GPIO_ADC_CT_POWER), // Current AGPIO(GPIO_ADC_JOY), // Joystick diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index dbcab5b1d..facaa1471 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -679,24 +679,24 @@ typedef struct { uint16_t light_wakeup; // 4A6 uint8_t knx_CB_registered; // 4A8 Number of Group Address to write uint8_t switchmode[MAX_SWITCHES_SET]; // 4A9 - uint8_t global_sensor_index[3]; // 4C9 4C5 - Moved up by 4 bytes in v14.3.0.7 - uint16_t dns_timeout; // 4CC 4C8 - uint8_t ds3502_state[MAX_DS3502]; // 4CE 4CA - uint16_t influxdb_port; // 4D2 4CE - power_t interlock[MAX_INTERLOCKS_SET]; // 4D4 4D0 MAX_INTERLOCKS = MAX_RELAYS / 2 - int8_t shutter_tilt_config[5][MAX_SHUTTERS]; // 514 508 - Moved up 12 bytes in v14.3.0.7 - int8_t shutter_tilt_pos[MAX_SHUTTERS]; // 528 51C - uint16_t influxdb_period; // 52C 520 - uint16_t rf_duplicate_time; // 52E 522 - int32_t weight_absconv_a; // 530 524 - int32_t weight_absconv_b; // 534 528 - uint16_t mqtt_keepalive; // 538 52C - uint16_t mqtt_socket_timeout; // 53A 52E - uint8_t mqtt_wifi_timeout; // 53C 530 - uint8_t ina219_mode; // 53D 531 - uint8_t weight_precision; // 53E 532 + uint8_t global_sensor_index[3]; // 4C5 + uint16_t dns_timeout; // 4C8 + uint8_t ds3502_state[MAX_DS3502]; // 4CA + uint16_t influxdb_port; // 4CE + power_t interlock[MAX_INTERLOCKS_SET]; // 4D0 MAX_INTERLOCKS = MAX_RELAYS / 2 + int8_t shutter_tilt_config[5][MAX_SHUTTERS]; //508 + int8_t shutter_tilt_pos[MAX_SHUTTERS]; //51C + uint16_t influxdb_period; // 520 + uint16_t rf_duplicate_time; // 522 + int32_t weight_absconv_a; // 524 + int32_t weight_absconv_b; // 528 + uint16_t mqtt_keepalive; // 52C + uint16_t mqtt_socket_timeout; // 52E + uint8_t mqtt_wifi_timeout; // 530 + uint8_t ina219_mode; // 531 + uint8_t weight_precision; // 532 ex_pulse_timer free since 11.0.0.3 - uint8_t free_53F; // 53F + uint8_t free_533[13]; // 533 uint16_t tcp_baudrate; // 540 uint16_t button_debounce; // 542 diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 8e6cd8138..c7f0d2d3f 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E030007; // 14.3.0.7 +const uint32_t TASMOTA_VERSION = 0x0E030006; // 14.3.0.6 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index 941f27968..abfb85484 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -1855,16 +1855,6 @@ void SettingsDelta(void) { char scolor[10]; WebHexCode(COL_BUTTON_OFF, GetTextIndexed(scolor, sizeof(scolor), COL_BUTTON_OFF, kWebColors)); } - if (Settings->version < 0x0E030007) { // 14.3.0.7 - memmove_P((uint8_t*)&Settings->shutter_tilt_config, (uint8_t*)&Settings->shutter_tilt_config - 12, 0x2B); - for (uint32_t i = 14; i < MAX_INTERLOCKS_SET; i++) { - Settings->interlock[i] = 0; - } - memmove_P((uint8_t*)&Settings->global_sensor_index, (uint8_t*)&Settings->global_sensor_index - 4, 0x43); - for (uint32_t i = 28; i < MAX_SWITCHES_SET; i++) { - Settings->switchmode[i] = SWITCH_MODE; - } - } Settings->version = TASMOTA_VERSION; SettingsSave(1); diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index 4c96ad7aa..d385ec0ac 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -832,7 +832,6 @@ int32_t UpdateDevicesPresent(int32_t change) { else if (devices_present >= POWER_SIZE) { // Support up to uint32_t as bitmask difference = devices_present - POWER_SIZE; devices_present = POWER_SIZE; - AddLog(LOG_LEVEL_DEBUG, PSTR("APP: Max number of devices reached")); } TasmotaGlobal.devices_present = devices_present; return difference; diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index e1ed6a7da..559e796c6 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -2882,11 +2882,11 @@ void CmndTouchCal(void) { if (XdrvMailbox.payload == 0) { TouchButton.calibration = 0; } - else if (XdrvMailbox.payload < MAX_KEYS) { + else if (XdrvMailbox.payload < MAX_KEYS + 1) { TouchButton.calibration = bitSet(TouchButton.calibration, XdrvMailbox.payload); } else if (XdrvMailbox.payload == 255) { - TouchButton.calibration = 0xFFFFFFFF; // All MAX_KEYS pins + TouchButton.calibration = 0x0FFFFFFF; // All MAX_KEYS pins } } ResponseCmndNumber(TouchButton.calibration); From 099c68678a5acdc43c146d6013c63d0cf35b5670 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 17 Nov 2024 13:15:36 +0100 Subject: [PATCH 138/205] prepare WPA Enterprise compile (#22497) * prep for WPA eap --- lib/default/WiFiHelper/src/WiFiHelper.h | 6 +++++- lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp | 9 +++++++++ .../tls_mini/src/WiFiClientSecureLightBearSSL.cpp | 4 +++- lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h | 2 +- tasmota/tasmota.ino | 2 +- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/default/WiFiHelper/src/WiFiHelper.h b/lib/default/WiFiHelper/src/WiFiHelper.h index 6abcf583a..6f4e1997f 100644 --- a/lib/default/WiFiHelper/src/WiFiHelper.h +++ b/lib/default/WiFiHelper/src/WiFiHelper.h @@ -59,7 +59,11 @@ typedef enum WiFiPhyMode class WiFiHelper { public: #ifdef ESP32 +#if __has_include("esp_eap_client.h") && __has_include("chip-debug-report.h") // check for Tasmota framework + static wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int ttls_phase2_type=-1, int32_t channel=0, const uint8_t* bssid=0, bool connect=true); +#else static wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int32_t channel=0, const uint8_t* bssid=0, bool connect=true); +#endif #endif static wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); static wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); @@ -94,4 +98,4 @@ public: -#endif // WIFIHELPER_H \ No newline at end of file +#endif // WIFIHELPER_H diff --git a/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp b/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp index 000840e81..cb9463041 100644 --- a/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp +++ b/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp @@ -34,12 +34,21 @@ ip_addr_t dns_save6[DNS_MAX_SERVERS] = {}; // IPv6 DNS servers #include "tasmota_options.h" #include "lwip/dns.h" +#if __has_include("esp_eap_client.h") && __has_include("chip-debug-report.h") // check for Tasmota framework +wl_status_t WiFiHelper::begin(const char *wpa2_ssid, wpa2_auth_method_t method, const char *wpa2_identity, const char *wpa2_username, const char *wpa2_password, const char *ca_pem, const char *client_crt, const char *client_key, int ttls_phase2_type, int32_t channel, const uint8_t *bssid, bool connect) { + WiFiHelper::scrubDNS(); + wl_status_t ret = WiFi.begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, ttls_phase2_type, channel, bssid, connect); + WiFiHelper::scrubDNS(); + return ret; +} +#else wl_status_t WiFiHelper::begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity, const char* wpa2_username, const char *wpa2_password, const char* ca_pem, const char* client_crt, const char* client_key, int32_t channel, const uint8_t* bssid, bool connect) { WiFiHelper::scrubDNS(); wl_status_t ret = WiFi.begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, channel, bssid, connect); WiFiHelper::scrubDNS(); return ret; } +#endif wl_status_t WiFiHelper::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { WiFiHelper::scrubDNS(); diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp index 540d37420..afbe3602e 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp @@ -47,7 +47,9 @@ #include "c_types.h" #endif -#include +#if __has_include("core_version.h") // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option +#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) +#endif // ESP32_STAGE #undef DEBUG_TLS #ifdef DEBUG_TLS diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h index 0ca24ec00..2c675d154 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef ESP32_STAGE // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option +#if __has_include("core_version.h") // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option #include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) #endif // ESP32_STAGE diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 1ec2500aa..94b611e1a 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -18,7 +18,7 @@ */ // Location specific includes -#ifndef ESP32_STAGE // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option +#if __has_include("core_version.h") // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option #include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) #endif // ESP32_STAGE #include "include/tasmota_compat.h" From 4e40bbf3b654f17e2109b8f009663a70fcebf4ca Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 17 Nov 2024 14:03:04 +0100 Subject: [PATCH 139/205] Bump version v14.3.0.7 - again - ESP32 max number of supported switches/buttons/relays from 28 to 32 - ESP32 max number of interlocks from 14 to 16 --- CHANGELOG.md | 15 +- RELEASENOTES.md | 4 +- .../HTTP_SCRIPT_MODULE_TEMPLATE.h | 24 +-- .../HTTP_SCRIPT_MODULE_TEMPLATE.h | 2 +- tasmota/include/tasmota.h | 13 +- tasmota/include/tasmota_template.h | 174 +++++++++--------- tasmota/include/tasmota_types.h | 16 +- tasmota/include/tasmota_version.h | 2 +- tasmota/tasmota_support/settings.ino | 19 ++ tasmota/tasmota_support/support.ino | 1 + tasmota/tasmota_support/support_command.ino | 4 +- 11 files changed, 151 insertions(+), 123 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d776ec2b4..dcef330d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,20 +3,27 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [14.3.0.6] +## [14.3.0.7] ### Added -- Add command ``WebColor20`` to control color of Button when Off ### Breaking Changed +### Fixed + +### Removed + ### Changed +- ESP32 max number of supported switches/buttons/relays from 28 to 32 +- ESP32 max number of interlocks from 14 to 16 + +## [14.3.0.6] 20241116 +### Added +- Add command ``WebColor20`` to control color of Button when Off ### Fixed - Matter provisioning with matter.js controller (#22470) - Prevent crashing when `display.ini` is missing end `#` (#22471) -### Removed - ## [14.3.0.5] 20241111 ### Added - ESP32 MI32 legacy add config operations (#22458) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index eac5e949c..ed100cf8d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -114,7 +114,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.3.0.6 +## Changelog v14.3.0.7 ### Added - Add command ``WebColor20`` to control color of Button when Off - DALI support for short addresses (gear) and groups @@ -157,6 +157,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default - Shutter optimized behavior to publish shutter data with sensor request [#22353](https://github.com/arendst/Tasmota/issues/22353) +- ESP32 max number of supported switches/buttons/relays from 28 to 32 +- ESP32 max number of interlocks from 14 to 16 - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed diff --git a/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h b/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h index e7f059b0b..99c40b1ac 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h @@ -2,7 +2,7 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 602; +const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 589; const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\xD4\x2B\xC7\x83\x02\xF8\x3A\xDC\xE4\x1B\x3B\xBA\x75\x1A\x8E\xF1" "\xED\x33\xBF\xAC\x3E\x09\x81\x8B\x1A\xFA\x8E\x81\xFD\xDD\x32\x61\x31\xAF\xA8\xEE" "\x9F\x78\x32\xB7\x38\xFB\x3B\xC7\x8C\x3A\x53\x36\x51\x07\x9D\x4F\xA8\xF9\xA7\x83" @@ -15,16 +15,16 @@ const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\ "\x0C\x3A\x7D\x8D\xC3\x36\x08\x3B\x70\x24\xE0\x87\x78\xF0\x7B\x82\x3E\x0A\x04\xAC" "\xC8\xE3\x3C\x16\x9E\x81\x1E\x34\xED\x9D\xB3\xBC\x7B\x43\x3E\x0A\xF1\xEF\x69\xEF" "\x82\x17\x2A\x01\xE7\x8D\x30\x77\x6C\xF8\x7C\x0C\xEF\x1E\xD1\xC0\x89\x50\xE3\x70" - "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x21\x64\x47\x21" - "\xE0\xB4\xF4\x3E\x0E\x04\x2C\x8D\x9D\xD3\xBB\xA7\xA1\xC8\xCE\xF1\xDA\x3B\xA7\xD9" - "\xDC\x3E\xCE\xD9\x69\xDE\x3C\xF4\xEA\xA3\xBC\x78\x3D\xCC\x71\xDD\x3E\xC5\x1F\x67" - "\x6C\x78\xEF\x1D\x0C\xEC\x21\x6C\xF8\x2C\xED\x9C\x87\x82\xA3\xA7\xA8\xC8\x26\x74" - "\x33\xDF\x68\xED\x0B\x68\xC8\xF8\x77\x47\x1F\x87\x19\xDE\x3B\x47\xD9\xF6\x79\x9F" - "\x64\x2B\x44\x11\xF1\xF6\x08\xDC\x58\xF8\xD0\xEE\xF8\xEA\x1E\x04\x3E\x42\xF3\xC7" - "\x4F\xB1\x81\x58\x6C\xEE\x9D\x87\xB8\xE5\x1D\x84\x3C\x75\x1E\xC3\xD0\x10\x78\x4B" - "\x40\x83\x9E\x9F\x67\xB0\xEF\x02\x35\xD3\x96\x76\x10\xF1\xD4\x7B\x0F\x43\xB0\x10" - "\x6F\x1F\x87\xB0\xEF\x1E\x18\xE3\xBA\x7D\x8F\x1F\x67\x6C\x78\xEF\x1D\x37\xB9\xFC" - "\x85\x15\x10\xD2\x08\xF9\x80\x8D\x48\x10\x72\x13\xBA\x3C\x7A\x1C\x48\xEF\x1D\xA2" - "\x04\x3E\x47\x4F\x3F\x1E\x34\xC0\x20\xD0\x3D\xA0\x85\xC9\xF9\xE0\xF7\x1E\xE3"; + "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x23\x64\x47\xC1" + "\xC0\x85\x91\xB3\xBB\xA7\x6C\xE4\x3A\x8A\x8E\xF1\xE0\xF7\x31\xC7\x74\xFB\x14\x7D" + "\x9D\xB1\xE3\xBC\x74\x33\xB0\x85\xB3\xE0\xB3\xB6\x72\x1E\x0A\x8E\x9E\xA3\x20\x99" + "\xD0\xCF\x7D\xA3\xB4\x2D\xA3\x23\xE1\xDD\x1C\x7E\x1C\x67\x78\xED\x1F\x67\xD9\xE6" + "\x7D\x90\xAD\x10\x47\xC7\xD8\x23\x71\x49\xE3\x43\xBB\xE3\xA8\x78\x10\xF8\xFE\xCF" + "\x1D\x3E\xC6\x05\x61\xB3\xBA\x76\x1E\xE3\x94\x76\x10\xF1\xD4\x7B\x0F\x40\x41\xE0" + "\xF9\x02\x0E\x7A\x7D\x9E\xC3\xBC\x08\xD7\x4E\x59\xD8\x43\xC7\x51\xEC\x3D\x0E\xC0" + "\x41\xBC\x7E\x1E\xC3\xBC\x78\x63\x8E\xE9\xF6\x3C\x7D\x9D\xB1\xE3\xBC\x74\xDE\xE7" + "\xF2\x14\x54\x43\x48\x23\xE6\x02\x35\x20\x41\xC8\x4E\xE8\xF1\xE8\x71\x23\xBC\x76" + "\x88\x10\xF9\x10\x3C\xFC\x78\xD3\x2A\x01\x83\x40\xF6\x82\x17\x26\x47\x83\xDC\x7B" + "\x8D"; #define HTTP_SCRIPT_MODULE_TEMPLATE Decompress(HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED,HTTP_SCRIPT_MODULE_TEMPLATE_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h b/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h index fd52afcc0..0fcd77c51 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h @@ -12,7 +12,7 @@ const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM = "l=hs.length;" // Find max indexes for s "for(i=0;i>=5;" // Add options - "for(i=1;i<=b;i++){ce((i<10)?(' '+i):i,t);}" + "for(i=0;i<=b;i++){ce(i+1,t);}" // Add index 1 to 32 "eb('h'+g).value=u+1;" // Set selected value "t.style.visibility=(b>0)?'':'hidden';" "}" diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index ca775b88e..81ce401f6 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -38,7 +38,6 @@ const uint32_t POWER_SIZE = 32; // Power (relay) bit count * Constants \*********************************************************************************************/ -// Why 28? Because in addition to relays there may be lights and uint32_t bitmap can hold up to 32 devices #ifdef ESP8266 const uint8_t MAX_RELAYS = 8; // Max number of relays selectable on GPIO const uint8_t MAX_INTERLOCKS = 4; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) @@ -46,17 +45,17 @@ const uint8_t MAX_SWITCHES = 8; // Max number of switches selectable const uint8_t MAX_KEYS = 8; // Max number of keys or buttons selectable on GPIO #endif // ESP8266 #ifdef ESP32 -const uint8_t MAX_RELAYS = 28; // Max number of relays selectable on GPIO -const uint8_t MAX_INTERLOCKS = 14; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) -const uint8_t MAX_SWITCHES = 28; // Max number of switches selectable on GPIO -const uint8_t MAX_KEYS = 28; // Max number of keys or buttons selectable on GPIO +const uint8_t MAX_RELAYS = 32; // Max number of relays selectable on GPIO +const uint8_t MAX_INTERLOCKS = 16; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) +const uint8_t MAX_SWITCHES = 32; // Max number of switches selectable on GPIO +const uint8_t MAX_KEYS = 32; // Max number of keys or buttons selectable on GPIO #endif // ESP32 const uint8_t MAX_RELAYS_SET = 32; // Max number of relays const uint8_t MAX_KEYS_SET = 32; // Max number of keys // Changes to the following MAX_ defines will impact settings layout -const uint8_t MAX_INTERLOCKS_SET = 14; // Max number of interlock groups (MAX_RELAYS_SET / 2) -const uint8_t MAX_SWITCHES_SET = 28; // Max number of switches +const uint8_t MAX_INTERLOCKS_SET = 16; // Max number of interlock groups (MAX_RELAYS_SET / 2) +const uint8_t MAX_SWITCHES_SET = 32; // Max number of switches const uint8_t MAX_LEDS = 4; // Max number of leds const uint8_t MAX_PWMS_LEGACY = 5; // Max number of PWM channels in first settings block - Legacy limit for ESP8266, but extended for ESP32 (see below) #ifdef ESP32 // Max number of PWM channels (total including extended) - ESP32 only diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index d4c324cfb..f570f8894 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -509,7 +509,7 @@ const char kSensorNamesFixed[] PROGMEM = D_SENSOR_USER; // Max number of GPIOs -#define MAX_I2C 0 // Display no index if one bus +#define MAX_I2C 1 // Display no index if one bus #ifdef USE_I2C_BUS2 #undef MAX_I2C #define MAX_I2C 2 @@ -533,46 +533,46 @@ const char kSensorNamesFixed[] PROGMEM = const uint16_t kGpioNiceList[] PROGMEM = { GPIO_NONE, // Not used - AGPIO(GPIO_OPTION_A) + MAX_OPTIONS_A, // Device specific options + AGPIO(GPIO_OPTION_A) + MAX_OPTIONS_A -1, // Device specific options #ifdef ESP32 - AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E, // Device module emulation + AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E -1, // Device module emulation #endif - AGPIO(GPIO_KEY1) + MAX_KEYS, // Buttons - AGPIO(GPIO_KEY1_NP) + MAX_KEYS, + AGPIO(GPIO_KEY1) + MAX_KEYS -1, // Buttons + AGPIO(GPIO_KEY1_NP) + MAX_KEYS -1, #ifdef ESP32 - AGPIO(GPIO_KEY1_PD) + MAX_KEYS, + AGPIO(GPIO_KEY1_PD) + MAX_KEYS -1, #endif - AGPIO(GPIO_KEY1_INV) + MAX_KEYS, - AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS, + AGPIO(GPIO_KEY1_INV) + MAX_KEYS -1, + AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS -1, #ifdef ESP32 - AGPIO(GPIO_KEY1_INV_PD) + MAX_KEYS, + AGPIO(GPIO_KEY1_INV_PD) + MAX_KEYS -1, #if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2) - AGPIO(GPIO_KEY1_TC) + MAX_KEYS, // Touch button + AGPIO(GPIO_KEY1_TC) + MAX_KEYS -1, // Touch button #endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 #endif - AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches - AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES, + AGPIO(GPIO_SWT1) + MAX_SWITCHES -1, // User connected external switches + AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES -1, #ifdef ESP32 - AGPIO(GPIO_SWT1_PD) + MAX_SWITCHES, + AGPIO(GPIO_SWT1_PD) + MAX_SWITCHES -1, #endif #ifdef ROTARY_V1 - AGPIO(GPIO_ROT1A) + MAX_ROTARIES, // Rotary A Pin - AGPIO(GPIO_ROT1B) + MAX_ROTARIES, // Rotary B Pin - AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES, // Rotary A Pin No Pullup - AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES, // Rotary B Pin No Pullup + AGPIO(GPIO_ROT1A) + MAX_ROTARIES -1, // Rotary A Pin + AGPIO(GPIO_ROT1B) + MAX_ROTARIES -1, // Rotary B Pin + AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES -1, // Rotary A Pin No Pullup + AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES -1, // Rotary B Pin No Pullup #endif - AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays - AGPIO(GPIO_REL1_INV) + MAX_RELAYS, - AGPIO(GPIO_REL1_BI) + MAX_RELAYS, // Bistable (Latching) two coil relays - AGPIO(GPIO_REL1_BI_INV) + MAX_RELAYS, - AGPIO(GPIO_LED1) + MAX_LEDS, // Leds - AGPIO(GPIO_LED1_INV) + MAX_LEDS, + AGPIO(GPIO_REL1) + MAX_RELAYS -1, // Relays + AGPIO(GPIO_REL1_INV) + MAX_RELAYS -1, + AGPIO(GPIO_REL1_BI) + MAX_RELAYS -1, // Bistable (Latching) two coil relays + AGPIO(GPIO_REL1_BI_INV) + MAX_RELAYS -1, + AGPIO(GPIO_LED1) + MAX_LEDS -1, // Leds + AGPIO(GPIO_LED1_INV) + MAX_LEDS -1, #ifdef USE_COUNTER - AGPIO(GPIO_CNTR1) + MAX_COUNTERS, // Counters - AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS, + AGPIO(GPIO_CNTR1) + MAX_COUNTERS -1, // Counters + AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS -1, #endif - AGPIO(GPIO_PWM1) + MAX_PWMS, // RGB Red or C Cold White - AGPIO(GPIO_PWM1_INV) + MAX_PWMS, // or extended PWM for ESP32 + AGPIO(GPIO_PWM1) + MAX_PWMS -1, // RGB Red or C Cold White + AGPIO(GPIO_PWM1_INV) + MAX_PWMS -1, // or extended PWM for ESP32 #ifdef USE_BUZZER AGPIO(GPIO_BUZZER), // Buzzer AGPIO(GPIO_BUZZER_INV), // Inverted buzzer @@ -580,8 +580,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_LEDLNK), // Link led AGPIO(GPIO_LEDLNK_INV), // Inverted link led #ifdef USE_BERRY - AGPIO(GPIO_INPUT) + MAX_SWITCHES, // Pure digital input to be read via Berry - AGPIO(GPIO_INTERRUPT) + MAX_SWITCHES, // Interrupt pins to be catched by Berry + AGPIO(GPIO_INPUT) + MAX_SWITCHES -1, // Pure digital input to be read via Berry + AGPIO(GPIO_INTERRUPT) + MAX_SWITCHES -1, // Interrupt pins to be catched by Berry #endif AGPIO(GPIO_OUTPUT_HI), // Fixed output high AGPIO(GPIO_OUTPUT_LO), // Fixed output low @@ -601,32 +601,32 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #ifdef USE_I2C - AGPIO(GPIO_I2C_SCL) + MAX_I2C, // I2C SCL - AGPIO(GPIO_I2C_SDA) + MAX_I2C, // I2C SDA + AGPIO(GPIO_I2C_SCL) + MAX_I2C -1, // I2C SCL + AGPIO(GPIO_I2C_SDA) + MAX_I2C -1, // I2C SDA #ifdef USE_PCF8574 AGPIO(GPIO_PCF8574_INT), // PCF8574 Interrupt #endif // USE_PCF8574 #ifdef USE_I2C_SERIAL - AGPIO(GPIO_I2C_SER_TX) + MAX_I2C, // I2C via Serial TX - AGPIO(GPIO_I2C_SER_RX) + MAX_I2C, // I2C via Serial RX + AGPIO(GPIO_I2C_SER_TX) + MAX_I2C -1, // I2C via Serial TX + AGPIO(GPIO_I2C_SER_RX) + MAX_I2C -1, // I2C via Serial RX #endif // USE_I2C_SERIAL #endif #if defined(USE_I2S_AUDIO) || defined (USE_I2S) - AGPIO(GPIO_I2S_MCLK) + MAX_I2S, // I2S master clock - AGPIO(GPIO_I2S_BCLK) + MAX_I2S, // I2S bit clock - AGPIO(GPIO_I2S_DOUT) + MAX_I2S, // I2S Out Data - AGPIO(GPIO_I2S_DAC) + 2, // I2S DAC Output - AGPIO(GPIO_I2S_WS) + MAX_I2S, // I2S word select - AGPIO(GPIO_I2S_DIN) + MAX_I2S, // I2S IN Data + AGPIO(GPIO_I2S_MCLK) + MAX_I2S -1, // I2S master clock + AGPIO(GPIO_I2S_BCLK) + MAX_I2S -1, // I2S bit clock + AGPIO(GPIO_I2S_DOUT) + MAX_I2S -1, // I2S Out Data + AGPIO(GPIO_I2S_DAC) + 2 -1, // I2S DAC Output + AGPIO(GPIO_I2S_WS) + MAX_I2S -1, // I2S word select + AGPIO(GPIO_I2S_DIN) + MAX_I2S -1, // I2S IN Data #endif #ifdef USE_SPI - AGPIO(GPIO_SPI_MISO) + MAX_SPI, // SPI MISO - AGPIO(GPIO_SPI_MOSI) + MAX_SPI, // SPI MOSI - AGPIO(GPIO_SPI_CLK) + MAX_SPI, // SPI Clk - AGPIO(GPIO_SPI_CS) + MAX_SPI, // SPI Chip Select - AGPIO(GPIO_SPI_DC) + MAX_SPI, // SPI Data Direction + AGPIO(GPIO_SPI_MISO) + MAX_SPI -1, // SPI MISO + AGPIO(GPIO_SPI_MOSI) + MAX_SPI -1, // SPI MOSI + AGPIO(GPIO_SPI_CLK) + MAX_SPI -1, // SPI Clk + AGPIO(GPIO_SPI_CS) + MAX_SPI -1, // SPI Chip Select + AGPIO(GPIO_SPI_DC) + MAX_SPI -1, // SPI Data Direction #ifdef USE_NRF24 AGPIO(GPIO_NRF24_CS), AGPIO(GPIO_NRF24_DC), @@ -642,7 +642,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MCP2515_CS), #endif // USE_MCP2515 #ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23SXX_CS) + MAX_MCP23XXX, + AGPIO(GPIO_MCP23SXX_CS) + MAX_MCP23XXX -1, #endif // USE_MCP23XXX_DRV #ifdef USE_SPI_LORA AGPIO(GPIO_LORA_CS), @@ -754,11 +754,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_DISPLAY_TM1621_SONOFF #ifdef USE_MAX31865 - AGPIO(GPIO_SSPI_MAX31865_CS1) + MAX_MAX31865S, + AGPIO(GPIO_SSPI_MAX31865_CS1) + MAX_MAX31865S -1, #endif #ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23XXX_INT) + MAX_MCP23XXX, + AGPIO(GPIO_MCP23XXX_INT) + MAX_MCP23XXX -1, #endif #ifdef USE_HDMI_CEC @@ -780,8 +780,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 #endif #ifdef USE_DS18x20 - AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20 - AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB) + MAX_DSB -1, // Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB_OUT) + MAX_DSB -1, // Pseudo Single wire DS18B20 or DS18S20 #endif // USE_DS18x20 #ifdef USE_LMT01 AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO @@ -797,7 +797,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_P9813_CLK), // P9813 CLOCK AGPIO(GPIO_P9813_DAT), // P9813 DATA #else - AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 0), // WS2812 Led string, using RMT on ESP32 + AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 1) -1, // WS2812 Led string, using RMT on ESP32 #endif // NEO_HW_P9813 #endif #ifdef USE_ARILUX_RF @@ -815,15 +815,15 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_SM16716 #ifdef USE_SM2135 AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK - AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT, // SM2135 DATA + AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT -1, // SM2135 DATA #endif // USE_SM2135 #ifdef USE_SM2335 AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK - AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT, // SM2335 DATA + AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT -1, // SM2335 DATA #endif // USE_SM2335 #ifdef USE_BP1658CJ AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK - AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT, // BP1658CJ DATA + AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT -1, // BP1658CJ DATA #endif // USE_BP1658CJ #ifdef USE_BP5758D AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK @@ -857,7 +857,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRSEND) + MAX_IRSEND, // IR remote + AGPIO(GPIO_IRSEND) + MAX_IRSEND -1, // IR remote #if defined(USE_IR_RECEIVE) || defined(USE_IR_REMOTE_FULL) AGPIO(GPIO_IRRECV), // IR receiver #endif @@ -870,8 +870,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding #endif #ifdef USE_SR04 - AGPIO(GPIO_SR04_TRIG) + MAX_SR04, // SR04 Tri/TXgger pin - AGPIO(GPIO_SR04_ECHO) + MAX_SR04, // SR04 Ech/RXo pin + AGPIO(GPIO_SR04_TRIG) + MAX_SR04 -1, // SR04 Tri/TXgger pin + AGPIO(GPIO_SR04_ECHO) + MAX_SR04 -1, // SR04 Ech/RXo pin #endif #ifdef USE_ME007 AGPIO(GPIO_ME007_TRIG), // ME007 Trigger pin (xsns_23_me007.ino) @@ -904,20 +904,20 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power #endif #if defined(USE_I2C) && defined(USE_ADE7880) - AGPIO(GPIO_ADE7880_IRQ) + 2, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) + AGPIO(GPIO_ADE7880_IRQ) + 2 -1, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) #endif #ifdef USE_ADE7953 #if defined(USE_I2C) || defined(USE_SPI) - AGPIO(GPIO_ADE7953_IRQ) + 6, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) + AGPIO(GPIO_ADE7953_IRQ) + 6 -1, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset #ifdef USE_SPI - AGPIO(GPIO_ADE7953_CS) + 2, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) + AGPIO(GPIO_ADE7953_CS) + 2 -1, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) #endif // USE_SPI #endif // USE_I2C or USE_SPI #endif // USE_ADE7953 #ifdef USE_CSE7761 AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) - AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) + AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761 -1, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) #endif #ifdef USE_CSE7766 AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) @@ -972,13 +972,13 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_LE01MR #ifdef ESP32 #ifdef USE_BL0906 - AGPIO(GPIO_BL0906_RX) + MAX_BL0906_RX, // BL0906 Serial interface (Athom EM6) + AGPIO(GPIO_BL0906_RX) + MAX_BL0906_RX -1, // BL0906 Serial interface (Athom EM6) #endif // USE_BL0906 #endif // ESP32 #if defined(USE_BL0940) || defined(USE_BL09XX) AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface - AGPIO(GPIO_BL0942_RX) + MAX_BL0942_RX, // BL0942 Serial interface + AGPIO(GPIO_BL0942_RX) + MAX_BL0942_RX -1, // BL0942 Serial interface #endif #ifdef USE_IEM3000 AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface @@ -1024,7 +1024,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_ZIGBEE AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RST) + 2, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode + AGPIO(GPIO_ZIGBEE_RST) + 2 -1, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode #endif #ifdef USE_MHZ19 AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface @@ -1147,7 +1147,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MGC3130_RESET), #endif #ifdef USE_MAX31855 - AGPIO(GPIO_MAX31855CS) + MAX_MAX31855S, //MAX31855 Serial interface + AGPIO(GPIO_MAX31855CS) + MAX_MAX31855S -1, //MAX31855 Serial interface AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface #endif @@ -1160,7 +1160,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_A4988_STP), // A4988 step pin // folowing are not mandatory AGPIO(GPIO_A4988_ENA), // A4988 enabled pin - AGPIO(GPIO_A4988_MS1) + MAX_A4988_MSS, // A4988 microstep pin1 to pin3 + AGPIO(GPIO_A4988_MS1) + MAX_A4988_MSS -1, // A4988 microstep pin1 to pin3 #endif #ifdef USE_DEEPSLEEP AGPIO(GPIO_DEEPSLEEP), @@ -1203,10 +1203,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control #endif #if defined(USE_VL53L0X) or defined (USE_VL53L1X) - AGPIO(GPIO_VL53LXX_XSHUT1) + VL53LXX_MAX_SENSORS, // When using multiple VL53LXX. + AGPIO(GPIO_VL53LXX_XSHUT1) + VL53LXX_MAX_SENSORS -1, // When using multiple VL53LXX. #endif #ifdef USE_FLOWRATEMETER - AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER, // Flow meter Pin + AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER -1, // Flow meter Pin #endif #ifdef USE_SHIFT595 @@ -1217,7 +1217,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #if defined (ESP32) && defined(USE_DINGTIAN_RELAY) - AGPIO(GPIO_DINGTIAN_CLK) + MAX_DINGTIAN_SHIFT, // Dingtian Relay board - 8,16,24 or 32 relays & inputs + AGPIO(GPIO_DINGTIAN_CLK) + MAX_DINGTIAN_SHIFT -1, // Dingtian Relay board - 8,16,24 or 32 relays & inputs AGPIO(GPIO_DINGTIAN_SDI), AGPIO(GPIO_DINGTIAN_Q7), AGPIO(GPIO_DINGTIAN_PL), @@ -1226,7 +1226,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #ifdef USE_MAGIC_SWITCH - AGPIO(GPIO_MAGIC_SWITCH) + MAX_MAGIC_SWITCH_MODES, + AGPIO(GPIO_MAGIC_SWITCH) + MAX_MAGIC_SWITCH_MODES -1, #endif #ifdef USE_PIPSOLAR // xdrv_92_pipsolar.ino @@ -1240,7 +1240,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef ESP32 #if CONFIG_IDF_TARGET_ESP32 - AGPIO(GPIO_HALLEFFECT) + 2, // Hall effect sensor connected to GPIO36 and 39 + AGPIO(GPIO_HALLEFFECT) + 2 -1, // Hall effect sensor connected to GPIO36 and 39 #endif // CONFIG_IDF_TARGET_ESP32 #ifdef USE_WEBCAM AGPIO(GPIO_WEBCAM_PWDN), @@ -1248,12 +1248,12 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_WEBCAM_XCLK), AGPIO(GPIO_WEBCAM_SIOD), AGPIO(GPIO_WEBCAM_SIOC), - AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA, + AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA -1, AGPIO(GPIO_WEBCAM_VSYNC), AGPIO(GPIO_WEBCAM_HREF), AGPIO(GPIO_WEBCAM_PCLK), AGPIO(GPIO_WEBCAM_PSCLK), - AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD, + AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD -1, AGPIO(GPIO_WEBCAM_PSRCS), #endif // USE_WEBCAM #ifdef USE_ETHERNET @@ -1264,25 +1264,25 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_BIOPDU AGPIO(GPIO_BIOPDU_PZEM0XX_TX), // Biomine BioPDU pins AGPIO(GPIO_BIOPDU_PZEM016_RX), - AGPIO(GPIO_BIOPDU_BIT) + 3, + AGPIO(GPIO_BIOPDU_BIT) + 3 -1, #endif /*-------------------------------------------------------------------------------------------*\ * ESP32 multiple Analog / Digital converter inputs \*-------------------------------------------------------------------------------------------*/ - AGPIO(GPIO_ADC_INPUT) + MAX_ADCS, // Analog inputs - AGPIO(GPIO_ADC_TEMP) + MAX_ADCS, // Thermistor - AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS, // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button - AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS, - AGPIO(GPIO_ADC_RANGE) + MAX_ADCS, // Range - AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS, // Current - AGPIO(GPIO_ADC_JOY) + MAX_ADCS, // Joystick - AGPIO(GPIO_ADC_PH) + MAX_ADCS, // Analog PH Sensor - AGPIO(GPIO_ADC_MQ) + MAX_ADCS, // Analog MQ Sensor - AGPIO(GPIO_ADC_VOLTAGE) + MAX_ADCS, // Voltage - AGPIO(GPIO_ADC_CURRENT) + MAX_ADCS, // Current + AGPIO(GPIO_ADC_INPUT) + MAX_ADCS -1, // Analog inputs + AGPIO(GPIO_ADC_TEMP) + MAX_ADCS -1, // Thermistor + AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS -1, // Light sensor + AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS -1, // Button + AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS -1, + AGPIO(GPIO_ADC_RANGE) + MAX_ADCS -1, // Range + AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS -1, // Current + AGPIO(GPIO_ADC_JOY) + MAX_ADCS -1, // Joystick + AGPIO(GPIO_ADC_PH) + MAX_ADCS -1, // Analog PH Sensor + AGPIO(GPIO_ADC_MQ) + MAX_ADCS -1, // Analog MQ Sensor + AGPIO(GPIO_ADC_VOLTAGE) + MAX_ADCS -1, // Voltage + AGPIO(GPIO_ADC_CURRENT) + MAX_ADCS -1, // Current #endif // ESP32 }; @@ -1296,8 +1296,8 @@ const uint16_t kAdcNiceList[] PROGMEM = { AGPIO(GPIO_ADC_INPUT), // Analog inputs AGPIO(GPIO_ADC_TEMP), // Thermistor AGPIO(GPIO_ADC_LIGHT), // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button - AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS, + AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS -1, // Button + AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS -1, AGPIO(GPIO_ADC_RANGE), // Range AGPIO(GPIO_ADC_CT_POWER), // Current AGPIO(GPIO_ADC_JOY), // Joystick diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index facaa1471..df347846c 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -677,17 +677,12 @@ typedef struct { uint8_t light_width; // 4A4 uint8_t knx_GA_registered; // 4A5 Number of Group Address to read uint16_t light_wakeup; // 4A6 - uint8_t knx_CB_registered; // 4A8 Number of Group Address to write - uint8_t switchmode[MAX_SWITCHES_SET]; // 4A9 - uint8_t global_sensor_index[3]; // 4C5 + uint8_t switchmode[MAX_SWITCHES_SET]; // 4A8 4A9 - Moved dn by 1 byte in v14.3.0.7 uint16_t dns_timeout; // 4C8 uint8_t ds3502_state[MAX_DS3502]; // 4CA uint16_t influxdb_port; // 4CE power_t interlock[MAX_INTERLOCKS_SET]; // 4D0 MAX_INTERLOCKS = MAX_RELAYS / 2 - int8_t shutter_tilt_config[5][MAX_SHUTTERS]; //508 - int8_t shutter_tilt_pos[MAX_SHUTTERS]; //51C - uint16_t influxdb_period; // 520 - uint16_t rf_duplicate_time; // 522 + int8_t shutter_tilt_config[5][MAX_SHUTTERS]; // 510 508 - - Moved up by 8 bytes in v14.3.0.7 int32_t weight_absconv_a; // 524 int32_t weight_absconv_b; // 528 uint16_t mqtt_keepalive; // 52C @@ -695,8 +690,13 @@ typedef struct { uint8_t mqtt_wifi_timeout; // 530 uint8_t ina219_mode; // 531 uint8_t weight_precision; // 532 ex_pulse_timer free since 11.0.0.3 + uint8_t knx_CB_registered; // 533 4A8 Number of Group Address to write + int8_t shutter_tilt_pos[MAX_SHUTTERS]; // 534 51C + uint16_t influxdb_period; // 538 520 + uint16_t rf_duplicate_time; // 53A 522 + uint8_t global_sensor_index[3]; // 53C 4C5 - uint8_t free_533[13]; // 533 + uint8_t free_53F[1]; // 53F uint16_t tcp_baudrate; // 540 uint16_t button_debounce; // 542 diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index c7f0d2d3f..8e6cd8138 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E030006; // 14.3.0.6 +const uint32_t TASMOTA_VERSION = 0x0E030007; // 14.3.0.7 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index abfb85484..8d5008efd 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -1856,6 +1856,25 @@ void SettingsDelta(void) { WebHexCode(COL_BUTTON_OFF, GetTextIndexed(scolor, sizeof(scolor), COL_BUTTON_OFF, kWebColors)); } + if (Settings->version < 0x0E030007) { // 14.3.0.7 + // move up uint8_t knx_CB_registered from 4A8 to 533 + memmove_P((uint8_t*)&Settings->knx_CB_registered, (uint8_t*)&Settings->switchmode, 1); + // move up uint8_t global_sensor_index[3] from 4C5 to 53C + memmove_P((uint8_t*)&Settings->global_sensor_index, (uint8_t*)&Settings->switchmode +29, 3); + // move dn uint8_t switchmode[MAX_SWITCHES_SET] from 4A9 to 4A8 + memmove_P((uint8_t*)&Settings->switchmode, (uint8_t*)&Settings->switchmode +1, 28); + for (uint32_t i = 28; i < MAX_SWITCHES_SET; i++) { + Settings->switchmode[i] = SWITCH_MODE; + } + // move up int8_t shutter_tilt_pos[MAX_SHUTTERS], uint16_t influxdb_period and uint16_t rf_duplicate_timefrom 51C to 534 + memmove_P((uint8_t*)&Settings->shutter_tilt_pos, (uint8_t*)&Settings->shutter_tilt_config +12, 8); + // move up int8_t shutter_tilt_config[5][MAX_SHUTTERS] from 508 to 510 + memmove_P((uint8_t*)&Settings->shutter_tilt_config, (uint8_t*)&Settings->shutter_tilt_config -8, 20); + for (uint32_t i = 14; i < MAX_INTERLOCKS_SET; i++) { + Settings->interlock[i] = 0; + } + } + Settings->version = TASMOTA_VERSION; SettingsSave(1); } diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index d385ec0ac..4c96ad7aa 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -832,6 +832,7 @@ int32_t UpdateDevicesPresent(int32_t change) { else if (devices_present >= POWER_SIZE) { // Support up to uint32_t as bitmask difference = devices_present - POWER_SIZE; devices_present = POWER_SIZE; + AddLog(LOG_LEVEL_DEBUG, PSTR("APP: Max number of devices reached")); } TasmotaGlobal.devices_present = devices_present; return difference; diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 559e796c6..e1ed6a7da 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -2882,11 +2882,11 @@ void CmndTouchCal(void) { if (XdrvMailbox.payload == 0) { TouchButton.calibration = 0; } - else if (XdrvMailbox.payload < MAX_KEYS + 1) { + else if (XdrvMailbox.payload < MAX_KEYS) { TouchButton.calibration = bitSet(TouchButton.calibration, XdrvMailbox.payload); } else if (XdrvMailbox.payload == 255) { - TouchButton.calibration = 0x0FFFFFFF; // All MAX_KEYS pins + TouchButton.calibration = 0xFFFFFFFF; // All MAX_KEYS pins } } ResponseCmndNumber(TouchButton.calibration); From f3bf8998ae1f16316ba421a1d93b4091863a8b1d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 17 Nov 2024 18:02:23 +0100 Subject: [PATCH 140/205] Fax MCP23xxx and PCF8574 last device --- tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino | 8 ++++---- tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino index 7c56f460c..53e01ddb4 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino @@ -190,11 +190,11 @@ int Pcf8574Pin(uint32_t gpio, uint32_t index = 0); int Pcf8574Pin(uint32_t gpio, uint32_t index) { uint16_t real_gpio = gpio << 5; uint16_t mask = 0xFFE0; - if (index < GPIO_ANY) { +// if (index < GPIO_ANY) { real_gpio += index; mask = 0xFFFF; - } - for (uint32_t i = 0; i < Pcf8574.max_connected_ports; i++) { +// } + for (uint32_t i = 0; i <= Pcf8574.max_connected_ports; i++) { if ((Pcf8574_pin[i] & mask) == real_gpio) { return i; // Pin number configured for gpio } @@ -208,7 +208,7 @@ bool Pcf8574PinUsed(uint32_t gpio, uint32_t index) { } uint32_t Pcf8574GetPin(uint32_t lpin) { - if (lpin < Pcf8574.max_connected_ports) { + if (lpin <= Pcf8574.max_connected_ports) { return Pcf8574_pin[lpin]; } else { return GPIO_NONE; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino index 3182362ad..c867692fd 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino @@ -430,11 +430,11 @@ int MCP23xPin(uint32_t gpio, uint32_t index = 0); int MCP23xPin(uint32_t gpio, uint32_t index) { uint16_t real_gpio = gpio << 5; uint16_t mask = 0xFFE0; - if (index < GPIO_ANY) { +// if (index < GPIO_ANY) { real_gpio += index; mask = 0xFFFF; - } - for (uint32_t i = 0; i < Mcp23x.max_pins; i++) { +// } + for (uint32_t i = 0; i <= Mcp23x.max_pins; i++) { if ((Mcp23x_gpio_pin[i] & mask) == real_gpio) { return i; // Pin number configured for gpio } @@ -448,7 +448,7 @@ bool MCP23xPinUsed(uint32_t gpio, uint32_t index) { } uint32_t MCP23xGetPin(uint32_t lpin) { - if (lpin < Mcp23x.max_pins) { + if (lpin <= Mcp23x.max_pins) { return Mcp23x_gpio_pin[lpin]; } else { return GPIO_NONE; From 7615b3c8f7451d6450a2f9733ec5db58205d7872 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 17 Nov 2024 18:36:54 +0100 Subject: [PATCH 141/205] Platform 2024.11.31 Tasmota Arduino Core 3.1.0.241117 based on IDF 5.3.1.241024 (#22504) * Platform 2024.11.31 * add `ttls_phase2_type` --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- lib/default/WiFiHelper/src/WiFiHelper.h | 4 ---- lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp | 9 --------- platformio_tasmota32.ini | 2 +- 4 files changed, 2 insertions(+), 15 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 62ccb0b74..44833251a 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.8 - - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241030 + - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241117 - [ ] 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/lib/default/WiFiHelper/src/WiFiHelper.h b/lib/default/WiFiHelper/src/WiFiHelper.h index 6f4e1997f..e9c404b86 100644 --- a/lib/default/WiFiHelper/src/WiFiHelper.h +++ b/lib/default/WiFiHelper/src/WiFiHelper.h @@ -59,11 +59,7 @@ typedef enum WiFiPhyMode class WiFiHelper { public: #ifdef ESP32 -#if __has_include("esp_eap_client.h") && __has_include("chip-debug-report.h") // check for Tasmota framework static wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int ttls_phase2_type=-1, int32_t channel=0, const uint8_t* bssid=0, bool connect=true); -#else - static wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int32_t channel=0, const uint8_t* bssid=0, bool connect=true); -#endif #endif static wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); static wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); diff --git a/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp b/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp index cb9463041..601496f9d 100644 --- a/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp +++ b/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp @@ -34,21 +34,12 @@ ip_addr_t dns_save6[DNS_MAX_SERVERS] = {}; // IPv6 DNS servers #include "tasmota_options.h" #include "lwip/dns.h" -#if __has_include("esp_eap_client.h") && __has_include("chip-debug-report.h") // check for Tasmota framework wl_status_t WiFiHelper::begin(const char *wpa2_ssid, wpa2_auth_method_t method, const char *wpa2_identity, const char *wpa2_username, const char *wpa2_password, const char *ca_pem, const char *client_crt, const char *client_key, int ttls_phase2_type, int32_t channel, const uint8_t *bssid, bool connect) { WiFiHelper::scrubDNS(); wl_status_t ret = WiFi.begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, ttls_phase2_type, channel, bssid, connect); WiFiHelper::scrubDNS(); return ret; } -#else -wl_status_t WiFiHelper::begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity, const char* wpa2_username, const char *wpa2_password, const char* ca_pem, const char* client_crt, const char* client_key, int32_t channel, const uint8_t* bssid, bool connect) { - WiFiHelper::scrubDNS(); - wl_status_t ret = WiFi.begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, channel, bssid, connect); - WiFiHelper::scrubDNS(); - return ret; -} -#endif wl_status_t WiFiHelper::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { WiFiHelper::scrubDNS(); diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 1647d9c5f..3b785d096 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -81,7 +81,7 @@ lib_ignore = ${esp32_defaults.lib_ignore} ccronexpr [core32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.11.30/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.11.31/platform-espressif32.zip platform_packages = build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} From 873bd3f211853c071cbc1ad5a034a48a18879a23 Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Sun, 17 Nov 2024 20:50:45 +0100 Subject: [PATCH 142/205] fix compilation with BLE 5 (#22506) --- tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino index 34432ff48..6d2bb789f 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino @@ -754,6 +754,7 @@ extern "C" { success = true; break; case 232: // set adv params via bytes() descriptor of size 5, + #ifndef CONFIG_BT_NIMBLE_EXT_ADV if(MI32.conCtx->buffer[0] == 5){ uint16_t itvl_min = MI32.conCtx->buffer[2] + (MI32.conCtx->buffer[3] << 8); uint16_t itvl_max = MI32.conCtx->buffer[4] + (MI32.conCtx->buffer[5] << 8); @@ -763,6 +764,7 @@ extern "C" { AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: adv params: type: %u, min: %u, max: %u"),MI32.conCtx->buffer[1], (uint16_t)(itvl_min * 0.625), (uint16_t)(itvl_max * 0.625)) ; success = true; } + #endif //CONFIG_BT_NIMBLE_EXT_ADV break; case 233: int ret = ble_svc_gap_device_name_set((const char*)MI32.conCtx->buffer + 1); @@ -1995,7 +1997,7 @@ void MI32parseBTHomePacket(char * _buf, uint32_t length, uint8_t addr[6], int RS idx += 3; break; case 0x0b: - // power ?? + // power in W idx += 4; break; case 0x0c: @@ -2003,11 +2005,15 @@ void MI32parseBTHomePacket(char * _buf, uint32_t length, uint8_t addr[6], int RS idx += 3; break; case 0x10: - // binary power on/off?? + // power on/off + idx += 2; + break; + case 0x11: + // opening closed=0/open=1 idx += 2; break; default: - AddLog(LOG_LEVEL_INFO,PSTR("M32: unknown BTHome data type: %u, discard rest of data buffer!"),_buf[idx]); + AddLog(LOG_LEVEL_INFO,PSTR("M32: unknown BTHome data type: %x, discard rest of data buffer!"),_buf[idx]); AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*)_buf,length); idx = length; // "break" break; From 3114c75a1d97212eb004eea656cddf68f99d68d2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:05:42 +0100 Subject: [PATCH 143/205] Update changelogs --- CHANGELOG.md | 10 ++++++---- RELEASENOTES.md | 3 ++- tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino | 4 ++-- tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcef330d4..01c64b5b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,14 @@ All notable changes to this project will be documented in this file. ### Breaking Changed -### Fixed - -### Removed - ### Changed - ESP32 max number of supported switches/buttons/relays from 28 to 32 - ESP32 max number of interlocks from 14 to 16 +- ESP32 Platform from 2024.11.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.241030 to v3.1.0.241117 and IDF to 5.3.1.241024 (#22504) + +### Fixed + +### Removed ## [14.3.0.6] 20241116 ### Added @@ -30,6 +31,7 @@ All notable changes to this project will be documented in this file. ### Changed - Redesign GUI adding feedback to buttons, shutters and lights +- Use command `WebButton1` to change GUI shutter 1 name ### Removed - Command ``SetOption161 1`` to disable web page slider updates by commands diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ed100cf8d..297e99b85 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -145,9 +145,10 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Breaking Changed ### Changed -- ESP32 Platform from 2024.09.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241030 and IDF to 5.3.1.241024 [#22384](https://github.com/arendst/Tasmota/issues/22384) +- ESP32 Platform from 2024.09.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241117 and IDF to 5.3.1.241024 [#22504](https://github.com/arendst/Tasmota/issues/22504) - ESP32 LVGL library from v9.2.0 to v9.2.2 [#22385](https://github.com/arendst/Tasmota/issues/22385) - Redesign GUI adding feedback to buttons, shutters and lights +- Use command `WebButton1` to change GUI shutter 1 name - Unit (k)VAr(h) to (k)var(h) [#22435](https://github.com/arendst/Tasmota/issues/22435) - AHT1X/AHT2X/AHT3X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) - SGP4X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino index 53e01ddb4..874cbd772 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino @@ -190,10 +190,10 @@ int Pcf8574Pin(uint32_t gpio, uint32_t index = 0); int Pcf8574Pin(uint32_t gpio, uint32_t index) { uint16_t real_gpio = gpio << 5; uint16_t mask = 0xFFE0; -// if (index < GPIO_ANY) { + if (index < GPIO_ANY) { real_gpio += index; mask = 0xFFFF; -// } + } for (uint32_t i = 0; i <= Pcf8574.max_connected_ports; i++) { if ((Pcf8574_pin[i] & mask) == real_gpio) { return i; // Pin number configured for gpio diff --git a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino index c867692fd..8cb1196ac 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino @@ -430,10 +430,10 @@ int MCP23xPin(uint32_t gpio, uint32_t index = 0); int MCP23xPin(uint32_t gpio, uint32_t index) { uint16_t real_gpio = gpio << 5; uint16_t mask = 0xFFE0; -// if (index < GPIO_ANY) { + if (index < GPIO_ANY) { real_gpio += index; mask = 0xFFFF; -// } + } for (uint32_t i = 0; i <= Mcp23x.max_pins; i++) { if ((Mcp23x_gpio_pin[i] & mask) == real_gpio) { return i; // Pin number configured for gpio From 320ad0e1d3182b9a8079cdd2a3c1914e84ffcef8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:09:23 +0100 Subject: [PATCH 144/205] Fix ESP32 upgrade by file upload response based on file size (#22500) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + .../xdrv_01_9_webserver.ino | 21 +++++++++++++------ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01c64b5b7..50a0f8fef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. - ESP32 Platform from 2024.11.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.241030 to v3.1.0.241117 and IDF to 5.3.1.241024 (#22504) ### Fixed +- ESP32 upgrade by file upload response based on file size (#22500) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 297e99b85..ee2aaedf1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -169,6 +169,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Standby Stage for MiElHVAC [#22430](https://github.com/arendst/Tasmota/issues/22430) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 [#22367](https://github.com/arendst/Tasmota/issues/22367) +- ESP32 Upgrade by file upload response based on file size [#22500](https://github.com/arendst/Tasmota/issues/22500) - ESP32 Arduino Core IPv6 zones used by Matter [#22378](https://github.com/arendst/Tasmota/issues/22378) - ESP32, ESP32-S2 and ESP32-S3 re-enable touch buttons [#22446](https://github.com/arendst/Tasmota/issues/22446) - ESP32-S3 UART output mode for Tx [#22426](https://github.com/arendst/Tasmota/issues/22426) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index a7ad95d34..856c9a46d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -368,23 +368,32 @@ const char HTTP_FORM_UPG[] PROGMEM = "
" "

" "
 " D_UPGRADE_BY_FILE_UPLOAD " "; -const char HTTP_FORM_RST_UPG[] PROGMEM = +const char HTTP_FORM_RST_UPG[] PROGMEM = // ESP8266 or ESP32 dual partition "
" "

" "
" + "onclick='" + "eb(\"f1\").style.display=\"none\";" // Disable display of form f1 + "eb(\"f2\").style.display=\"block\";" // Enable display of D_UPLOAD_STARTED + "this.form.action+=this.form[\"u2\"].files[0].size;" // Set return file size + "this.form.submit();" // Form response + "'>%s" "
" "" ""; // upload via factory partition -const char HTTP_FORM_RST_UPG_FCT[] PROGMEM = +const char HTTP_FORM_RST_UPG_FCT[] PROGMEM = // ESP32 safeboot partition "
" "

" "
" + "onclick='" + "eb(\"f1\").style.display=\"none\";" // Disable display of form f1 + "var fs=this.form[\"u2\"].files[0].size;" // Retreive file size of requested file + "eb((fs>900000)?\"f3\":\"f2\").style.display=\"block\";" // Enable display of either D_UPLOAD_FACTORY or D_UPLOAD_STARTED based on arbitrary file size of 900k + "this.form.action+=fs;" // Set return file size + "return upl(this);" // Form response + "'>%s" "" "" "" From 3778f22d7bf59e6ca06d66d5e432905d1f8e6e02 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 18 Nov 2024 22:53:07 +0100 Subject: [PATCH 145/205] Fix wrong GUI Module and Template drop down list indexes regression --- CHANGELOG.md | 1 + tasmota/include/tasmota.h | 2 +- tasmota/include/tasmota_globals.h | 1 + tasmota/include/tasmota_template.h | 636 +++++++++--------- tasmota/tasmota_support/support_command.ino | 4 +- .../xdrv_01_9_webserver.ino | 4 +- 6 files changed, 325 insertions(+), 323 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50a0f8fef..5cef53e8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file. ### Fixed - ESP32 upgrade by file upload response based on file size (#22500) +- Wrong GUI Module and Template drop down list indexes regression ### Removed diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index 81ce401f6..fccfc5b66 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -107,7 +107,7 @@ const uint8_t MAX_I2S = 2; // Max number of Hardware I2S contro const uint8_t MAX_RMT = 0; // Max number or RMT channels (0 if unknown) #endif #else -const uint8_t MAX_SPI = 0; // Max number of Hardware SPI controllers (ESP8266 = 0, no choice) +const uint8_t MAX_SPI = 1; // Max number of Hardware SPI controllers const uint8_t MAX_I2S = 0; // Max number of Hardware I2S controllers (ESP8266 = 0, no choice) const uint8_t MAX_RMT = 0; // No RMT channel on ESP8266 #endif diff --git a/tasmota/include/tasmota_globals.h b/tasmota/include/tasmota_globals.h index 7e6ba23b3..7c02d9f7f 100644 --- a/tasmota/include/tasmota_globals.h +++ b/tasmota/include/tasmota_globals.h @@ -543,6 +543,7 @@ const char kWebColors[] PROGMEM = #define AGPIO(x) ((x)<<5) #define BGPIO(x) ((x)>>5) +#define AGMAX(x) ((x)?(x-1):0) #ifdef USE_DEVICE_GROUPS #define SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, ...) _SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, __VA_ARGS__, 0) diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index f570f8894..0a0ce7e71 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -509,90 +509,90 @@ const char kSensorNamesFixed[] PROGMEM = D_SENSOR_USER; // Max number of GPIOs -#define MAX_I2C 1 // Display no index if one bus +#define MAX_I2C 1 // Display no index if one bus #ifdef USE_I2C_BUS2 #undef MAX_I2C -#define MAX_I2C 2 +#define MAX_I2C 2 #endif -#define MAX_MAX31855S 6 -#define MAX_MAX31865S 6 -#define MAX_MCP23XXX 6 -#define MAX_FLOWRATEMETER 2 -#define MAX_A4988_MSS 3 -#define MAX_WEBCAM_DATA 8 -#define MAX_WEBCAM_HSD 3 -#define MAX_SM2135_DAT 10 -#define MAX_SM2335_DAT 16 -#define MAX_DSB 4 -#define MAX_BP1658CJ_DAT 16 -#define MAX_DINGTIAN_SHIFT 4 +#define MAX_MAX31855S 6 +#define MAX_MAX31865S 6 +#define MAX_MCP23XXX 6 +#define MAX_FLOWRATEMETER 2 +#define MAX_A4988_MSS 3 +#define MAX_WEBCAM_DATA 8 +#define MAX_WEBCAM_HSD 3 +#define MAX_SM2135_DAT 10 +#define MAX_SM2335_DAT 16 +#define MAX_DSB 4 +#define MAX_BP1658CJ_DAT 16 +#define MAX_DINGTIAN_SHIFT 4 #define MAX_MAGIC_SWITCH_MODES 2 -#define MAX_BL0906_RX 6 // Model number of phases, 2 (EM2), 6 (EM6) -#define MAX_BL0942_RX 8 // Baudrates 1/5 (4800), 2/6 (9600), 3/7 (19200), 4/8 (38400), Support Positive values only 1..4, Support also negative values 5..8 -#define MAX_CSE7761 2 // Model 1/2 (DUALR3), 2/2 (POWCT) +#define MAX_BL0906_RX 6 // Model number of phases, 2 (EM2), 6 (EM6) +#define MAX_BL0942_RX 8 // Baudrates 1/5 (4800), 2/6 (9600), 3/7 (19200), 4/8 (38400), Support Positive values only 1..4, Support also negative values 5..8 +#define MAX_CSE7761 2 // Model 1/2 (DUALR3), 2/2 (POWCT) const uint16_t kGpioNiceList[] PROGMEM = { - GPIO_NONE, // Not used - AGPIO(GPIO_OPTION_A) + MAX_OPTIONS_A -1, // Device specific options + GPIO_NONE, // Not used + AGPIO(GPIO_OPTION_A) + AGMAX(MAX_OPTIONS_A), // Device specific options #ifdef ESP32 - AGPIO(GPIO_OPTION_E) + MAX_OPTIONS_E -1, // Device module emulation + AGPIO(GPIO_OPTION_E) + AGMAX(MAX_OPTIONS_E), // Device module emulation #endif - AGPIO(GPIO_KEY1) + MAX_KEYS -1, // Buttons - AGPIO(GPIO_KEY1_NP) + MAX_KEYS -1, + AGPIO(GPIO_KEY1) + AGMAX(MAX_KEYS), // Buttons + AGPIO(GPIO_KEY1_NP) + AGMAX(MAX_KEYS), #ifdef ESP32 - AGPIO(GPIO_KEY1_PD) + MAX_KEYS -1, + AGPIO(GPIO_KEY1_PD) + AGMAX(MAX_KEYS), #endif - AGPIO(GPIO_KEY1_INV) + MAX_KEYS -1, - AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS -1, + AGPIO(GPIO_KEY1_INV) + AGMAX(MAX_KEYS), + AGPIO(GPIO_KEY1_INV_NP) + AGMAX(MAX_KEYS), #ifdef ESP32 - AGPIO(GPIO_KEY1_INV_PD) + MAX_KEYS -1, + AGPIO(GPIO_KEY1_INV_PD) + AGMAX(MAX_KEYS), #if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2) - AGPIO(GPIO_KEY1_TC) + MAX_KEYS -1, // Touch button + AGPIO(GPIO_KEY1_TC) + AGMAX(MAX_KEYS), // Touch button #endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 #endif - AGPIO(GPIO_SWT1) + MAX_SWITCHES -1, // User connected external switches - AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES -1, + AGPIO(GPIO_SWT1) + AGMAX(MAX_SWITCHES), // User connected external switches + AGPIO(GPIO_SWT1_NP) + AGMAX(MAX_SWITCHES), #ifdef ESP32 - AGPIO(GPIO_SWT1_PD) + MAX_SWITCHES -1, + AGPIO(GPIO_SWT1_PD) + AGMAX(MAX_SWITCHES), #endif #ifdef ROTARY_V1 - AGPIO(GPIO_ROT1A) + MAX_ROTARIES -1, // Rotary A Pin - AGPIO(GPIO_ROT1B) + MAX_ROTARIES -1, // Rotary B Pin - AGPIO(GPIO_ROT1A_NP) + MAX_ROTARIES -1, // Rotary A Pin No Pullup - AGPIO(GPIO_ROT1B_NP) + MAX_ROTARIES -1, // Rotary B Pin No Pullup + AGPIO(GPIO_ROT1A) + AGMAX(MAX_ROTARIES), // Rotary A Pin + AGPIO(GPIO_ROT1B) + AGMAX(MAX_ROTARIES), // Rotary B Pin + AGPIO(GPIO_ROT1A_NP) + AGMAX(MAX_ROTARIES), // Rotary A Pin No Pullup + AGPIO(GPIO_ROT1B_NP) + AGMAX(MAX_ROTARIES), // Rotary B Pin No Pullup #endif - AGPIO(GPIO_REL1) + MAX_RELAYS -1, // Relays - AGPIO(GPIO_REL1_INV) + MAX_RELAYS -1, - AGPIO(GPIO_REL1_BI) + MAX_RELAYS -1, // Bistable (Latching) two coil relays - AGPIO(GPIO_REL1_BI_INV) + MAX_RELAYS -1, - AGPIO(GPIO_LED1) + MAX_LEDS -1, // Leds - AGPIO(GPIO_LED1_INV) + MAX_LEDS -1, + AGPIO(GPIO_REL1) + AGMAX(MAX_RELAYS), // Relays + AGPIO(GPIO_REL1_INV) + AGMAX(MAX_RELAYS), + AGPIO(GPIO_REL1_BI) + AGMAX(MAX_RELAYS), // Bistable (Latching) two coil relays + AGPIO(GPIO_REL1_BI_INV) + AGMAX(MAX_RELAYS), + AGPIO(GPIO_LED1) + AGMAX(MAX_LEDS), // Leds + AGPIO(GPIO_LED1_INV) + AGMAX(MAX_LEDS), #ifdef USE_COUNTER - AGPIO(GPIO_CNTR1) + MAX_COUNTERS -1, // Counters - AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS -1, + AGPIO(GPIO_CNTR1) + AGMAX(MAX_COUNTERS), // Counters + AGPIO(GPIO_CNTR1_NP) + AGMAX(MAX_COUNTERS), #endif - AGPIO(GPIO_PWM1) + MAX_PWMS -1, // RGB Red or C Cold White - AGPIO(GPIO_PWM1_INV) + MAX_PWMS -1, // or extended PWM for ESP32 + AGPIO(GPIO_PWM1) + AGMAX(MAX_PWMS), // RGB Red or C Cold White + AGPIO(GPIO_PWM1_INV) + AGMAX(MAX_PWMS), // or extended PWM for ESP32 #ifdef USE_BUZZER - AGPIO(GPIO_BUZZER), // Buzzer - AGPIO(GPIO_BUZZER_INV), // Inverted buzzer + AGPIO(GPIO_BUZZER), // Buzzer + AGPIO(GPIO_BUZZER_INV), // Inverted buzzer #endif - AGPIO(GPIO_LEDLNK), // Link led - AGPIO(GPIO_LEDLNK_INV), // Inverted link led + AGPIO(GPIO_LEDLNK), // Link led + AGPIO(GPIO_LEDLNK_INV), // Inverted link led #ifdef USE_BERRY - AGPIO(GPIO_INPUT) + MAX_SWITCHES -1, // Pure digital input to be read via Berry - AGPIO(GPIO_INTERRUPT) + MAX_SWITCHES -1, // Interrupt pins to be catched by Berry + AGPIO(GPIO_INPUT) + AGMAX(MAX_SWITCHES), // Pure digital input to be read via Berry + AGPIO(GPIO_INTERRUPT) + AGMAX(MAX_SWITCHES), // Interrupt pins to be catched by Berry #endif - AGPIO(GPIO_OUTPUT_HI), // Fixed output high - AGPIO(GPIO_OUTPUT_LO), // Fixed output low - AGPIO(GPIO_HEARTBEAT), // Every second pulsed high - AGPIO(GPIO_HEARTBEAT_INV), // Every second pulsed low - AGPIO(GPIO_RESET), // Generic reset + AGPIO(GPIO_OUTPUT_HI), // Fixed output high + AGPIO(GPIO_OUTPUT_LO), // Fixed output low + AGPIO(GPIO_HEARTBEAT), // Every second pulsed high + AGPIO(GPIO_HEARTBEAT_INV), // Every second pulsed low + AGPIO(GPIO_RESET), // Generic reset #ifdef USE_FTC532 - AGPIO(GPIO_FTC532), // FTC532 touch input + AGPIO(GPIO_FTC532), // FTC532 touch input #endif #ifdef USE_BS814A2 - AGPIO(GPIO_BS814_CLK), // Holtek BS814A2 touch ctrlr + AGPIO(GPIO_BS814_CLK), // Holtek BS814A2 touch ctrlr AGPIO(GPIO_BS814_DAT), #endif @@ -601,48 +601,48 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #ifdef USE_I2C - AGPIO(GPIO_I2C_SCL) + MAX_I2C -1, // I2C SCL - AGPIO(GPIO_I2C_SDA) + MAX_I2C -1, // I2C SDA + AGPIO(GPIO_I2C_SCL) + AGMAX(MAX_I2C), // I2C SCL + AGPIO(GPIO_I2C_SDA) + AGMAX(MAX_I2C), // I2C SDA #ifdef USE_PCF8574 - AGPIO(GPIO_PCF8574_INT), // PCF8574 Interrupt + AGPIO(GPIO_PCF8574_INT), // PCF8574 Interrupt #endif // USE_PCF8574 #ifdef USE_I2C_SERIAL - AGPIO(GPIO_I2C_SER_TX) + MAX_I2C -1, // I2C via Serial TX - AGPIO(GPIO_I2C_SER_RX) + MAX_I2C -1, // I2C via Serial RX + AGPIO(GPIO_I2C_SER_TX) + AGMAX(MAX_I2C), // I2C via Serial TX + AGPIO(GPIO_I2C_SER_RX) + AGMAX(MAX_I2C), // I2C via Serial RX #endif // USE_I2C_SERIAL #endif #if defined(USE_I2S_AUDIO) || defined (USE_I2S) - AGPIO(GPIO_I2S_MCLK) + MAX_I2S -1, // I2S master clock - AGPIO(GPIO_I2S_BCLK) + MAX_I2S -1, // I2S bit clock - AGPIO(GPIO_I2S_DOUT) + MAX_I2S -1, // I2S Out Data - AGPIO(GPIO_I2S_DAC) + 2 -1, // I2S DAC Output - AGPIO(GPIO_I2S_WS) + MAX_I2S -1, // I2S word select - AGPIO(GPIO_I2S_DIN) + MAX_I2S -1, // I2S IN Data + AGPIO(GPIO_I2S_MCLK) + AGMAX(MAX_I2S), // I2S master clock + AGPIO(GPIO_I2S_BCLK) + AGMAX(MAX_I2S), // I2S bit clock + AGPIO(GPIO_I2S_DOUT) + AGMAX(MAX_I2S), // I2S Out Data + AGPIO(GPIO_I2S_DAC) + AGMAX(2), // I2S DAC Output + AGPIO(GPIO_I2S_WS) + AGMAX(MAX_I2S), // I2S word select + AGPIO(GPIO_I2S_DIN) + AGMAX(MAX_I2S), // I2S IN Data #endif #ifdef USE_SPI - AGPIO(GPIO_SPI_MISO) + MAX_SPI -1, // SPI MISO - AGPIO(GPIO_SPI_MOSI) + MAX_SPI -1, // SPI MOSI - AGPIO(GPIO_SPI_CLK) + MAX_SPI -1, // SPI Clk - AGPIO(GPIO_SPI_CS) + MAX_SPI -1, // SPI Chip Select - AGPIO(GPIO_SPI_DC) + MAX_SPI -1, // SPI Data Direction + AGPIO(GPIO_SPI_MISO) + AGMAX(MAX_SPI), // SPI MISO + AGPIO(GPIO_SPI_MOSI) + AGMAX(MAX_SPI), // SPI MOSI + AGPIO(GPIO_SPI_CLK) + AGMAX(MAX_SPI), // SPI Clk + AGPIO(GPIO_SPI_CS) + AGMAX(MAX_SPI), // SPI Chip Select + AGPIO(GPIO_SPI_DC) + AGMAX(MAX_SPI), // SPI Data Direction #ifdef USE_NRF24 AGPIO(GPIO_NRF24_CS), AGPIO(GPIO_NRF24_DC), #endif #ifdef USE_RC522 - AGPIO(GPIO_RC522_CS), // RC522 Rfid Chip Select - AGPIO(GPIO_RC522_RST), // RC522 Rfid Reset + AGPIO(GPIO_RC522_CS), // RC522 Rfid Chip Select + AGPIO(GPIO_RC522_RST), // RC522 Rfid Reset #endif #ifdef USE_SDCARD - AGPIO(GPIO_SDCARD_CS), // SDCard in SPI mode + AGPIO(GPIO_SDCARD_CS), // SDCard in SPI mode #endif // USE_SDCARD #if defined(USE_MCP2515) || defined(USE_CANSNIFFER) AGPIO(GPIO_MCP2515_CS), #endif // USE_MCP2515 #ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23SXX_CS) + MAX_MCP23XXX -1, + AGPIO(GPIO_MCP23SXX_CS) + AGMAX(MAX_MCP23XXX), #endif // USE_MCP23XXX_DRV #ifdef USE_SPI_LORA AGPIO(GPIO_LORA_CS), @@ -658,25 +658,25 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_SPI #if defined(USE_SDCARD) && defined(ESP32) - AGPIO(GPIO_SDIO_CMD), // SDCard in SDIO mode + AGPIO(GPIO_SDIO_CMD), // SDCard in SDIO mode AGPIO(GPIO_SDIO_CLK), AGPIO(GPIO_SDIO_D0), - AGPIO(GPIO_SDIO_D1), // (opt) if in 4-bit mode, DAT1-3 are needed + AGPIO(GPIO_SDIO_D1), // (opt) if in 4-bit mode, DAT1-3 are needed AGPIO(GPIO_SDIO_D2), AGPIO(GPIO_SDIO_D3), #endif // USE_SDCARD - AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output - AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input - AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock - AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select - AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command + AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output + AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input + AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock + AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select + AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command #if defined(USE_DISPLAY) || defined(USE_LVGL) #ifdef USE_UNIVERSAL_TOUCH - AGPIO(GPIO_TS_SPI_CS), // Touch CS - AGPIO(GPIO_TS_RST), // Touch Reset - AGPIO(GPIO_TS_IRQ), // Touch IRQ + AGPIO(GPIO_TS_SPI_CS), // Touch CS + AGPIO(GPIO_TS_RST), // Touch Reset + AGPIO(GPIO_TS_IRQ), // Touch IRQ #endif // USE_UNIVERSAL_TOUCH // REMOVED // #ifdef USE_DISPLAY_ILI9341 @@ -685,7 +685,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { // #endif // USE_DISPLAY_ILI9341 #ifdef USE_XPT2046 - AGPIO(GPIO_XPT2046_CS), // XPT2046 SPI Chip Select + AGPIO(GPIO_XPT2046_CS), // XPT2046 SPI Chip Select #endif #ifdef USE_DISPLAY_ILI9488 @@ -738,10 +738,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_TM1640CLK), AGPIO(GPIO_TM1640DIN), #endif // USE_DISPLAY_TM1640 - AGPIO(GPIO_BACKLIGHT), // Display backlight control - AGPIO(GPIO_OLED_RESET), // OLED Display Reset + AGPIO(GPIO_BACKLIGHT), // Display backlight control + AGPIO(GPIO_OLED_RESET), // OLED Display Reset #ifdef ESP32 - AGPIO(GPIO_EPD_DATA), // Base connection EPD driver + AGPIO(GPIO_EPD_DATA), // Base connection EPD driver #endif #endif // USE_DISPLAY @@ -754,37 +754,37 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_DISPLAY_TM1621_SONOFF #ifdef USE_MAX31865 - AGPIO(GPIO_SSPI_MAX31865_CS1) + MAX_MAX31865S -1, + AGPIO(GPIO_SSPI_MAX31865_CS1) + AGMAX(MAX_MAX31865S), #endif #ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23XXX_INT) + MAX_MCP23XXX -1, + AGPIO(GPIO_MCP23XXX_INT) + AGMAX(MAX_MCP23XXX), #endif #ifdef USE_HDMI_CEC - AGPIO(GPIO_HDMI_CEC), // HDMI CEC bus + AGPIO(GPIO_HDMI_CEC), // HDMI CEC bus #endif - AGPIO(GPIO_TXD), // Serial interface - AGPIO(GPIO_RXD), // Serial interface + AGPIO(GPIO_TXD), // Serial interface + AGPIO(GPIO_RXD), // Serial interface /*-------------------------------------------------------------------------------------------*\ * Single wire sensors \*-------------------------------------------------------------------------------------------*/ #ifdef USE_DHT - AGPIO(GPIO_DHT11), // DHT11 - AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 - AGPIO(GPIO_SI7021), // iTead SI7021 - AGPIO(GPIO_MS01), // Sonoff MS01 - AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 + AGPIO(GPIO_DHT11), // DHT11 + AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 + AGPIO(GPIO_SI7021), // iTead SI7021 + AGPIO(GPIO_MS01), // Sonoff MS01 + AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 #endif #ifdef USE_DS18x20 - AGPIO(GPIO_DSB) + MAX_DSB -1, // Single wire DS18B20 or DS18S20 - AGPIO(GPIO_DSB_OUT) + MAX_DSB -1, // Pseudo Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB) + AGMAX(MAX_DSB), // Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB_OUT) + AGMAX(MAX_DSB), // Pseudo Single wire DS18B20 or DS18S20 #endif // USE_DS18x20 #ifdef USE_LMT01 - AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO + AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO #endif /*-------------------------------------------------------------------------------------------*\ @@ -794,47 +794,47 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_LIGHT #ifdef USE_WS2812 #if (USE_WS2812_HARDWARE == NEO_HW_P9813) - AGPIO(GPIO_P9813_CLK), // P9813 CLOCK - AGPIO(GPIO_P9813_DAT), // P9813 DATA + AGPIO(GPIO_P9813_CLK), // P9813 CLOCK + AGPIO(GPIO_P9813_DAT), // P9813 DATA #else - AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 1) -1, // WS2812 Led string, using RMT on ESP32 + AGPIO(GPIO_WS2812) + AGMAX(MAX_RMT), // WS2812 Led string, using RMT on ESP32 #endif // NEO_HW_P9813 #endif #ifdef USE_ARILUX_RF - AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input - AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected + AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input + AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected #endif #ifdef USE_MY92X1 - AGPIO(GPIO_DI), // my92x1 PWM input - AGPIO(GPIO_DCKI), // my92x1 CLK input + AGPIO(GPIO_DI), // my92x1 PWM input + AGPIO(GPIO_DCKI), // my92x1 CLK input #endif // USE_MY92X1 #ifdef USE_SM16716 - AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK - AGPIO(GPIO_SM16716_DAT), // SM16716 DATA - AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT + AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK + AGPIO(GPIO_SM16716_DAT), // SM16716 DATA + AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT #endif // USE_SM16716 #ifdef USE_SM2135 - AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK - AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT -1, // SM2135 DATA + AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK + AGPIO(GPIO_SM2135_DAT) + AGMAX(MAX_SM2135_DAT), // SM2135 DATA #endif // USE_SM2135 #ifdef USE_SM2335 - AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK - AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT -1, // SM2335 DATA + AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK + AGPIO(GPIO_SM2335_DAT) + AGMAX(MAX_SM2335_DAT), // SM2335 DATA #endif // USE_SM2335 #ifdef USE_BP1658CJ - AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK - AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT -1, // BP1658CJ DATA + AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK + AGPIO(GPIO_BP1658CJ_DAT) + AGMAX(MAX_BP1658CJ_DAT), // BP1658CJ DATA #endif // USE_BP1658CJ #ifdef USE_BP5758D - AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK - AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA + AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK + AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA #endif // USE_BP5758D #ifdef USE_TUYA_MCU - AGPIO(GPIO_TUYA_TX), // Tuya Serial interface - AGPIO(GPIO_TUYA_RX), // Tuya Serial interface + AGPIO(GPIO_TUYA_TX), // Tuya Serial interface + AGPIO(GPIO_TUYA_RX), // Tuya Serial interface #endif #ifdef USE_EXS_DIMMER - AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable + AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable #endif #ifdef USE_ELECTRIQ_MOODL AGPIO(GPIO_ELECTRIQ_MOODL_TX), @@ -846,10 +846,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_LIGHT #ifdef USE_DALI - AGPIO(GPIO_DALI_TX), // DALI TX - AGPIO(GPIO_DALI_TX_INV), // DALI TX inverted - AGPIO(GPIO_DALI_RX), // DALI RX - AGPIO(GPIO_DALI_RX_INV), // DALI RX inverted + AGPIO(GPIO_DALI_TX), // DALI TX + AGPIO(GPIO_DALI_TX_INV), // DALI TX inverted + AGPIO(GPIO_DALI_RX), // DALI RX + AGPIO(GPIO_DALI_RX_INV), // DALI RX inverted #endif // USE_DALI /*-------------------------------------------------------------------------------------------*\ @@ -857,38 +857,38 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRSEND) + MAX_IRSEND -1, // IR remote + AGPIO(GPIO_IRSEND) + AGMAX(MAX_IRSEND), // IR remote #if defined(USE_IR_RECEIVE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRRECV), // IR receiver + AGPIO(GPIO_IRRECV), // IR receiver #endif #endif #ifdef USE_RC_SWITCH - AGPIO(GPIO_RFSEND), // RF transmitter - AGPIO(GPIO_RFRECV), // RF receiver + AGPIO(GPIO_RFSEND), // RF transmitter + AGPIO(GPIO_RFRECV), // RF receiver #endif #ifdef USE_RF_SENSOR - AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding + AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding #endif #ifdef USE_SR04 - AGPIO(GPIO_SR04_TRIG) + MAX_SR04 -1, // SR04 Tri/TXgger pin - AGPIO(GPIO_SR04_ECHO) + MAX_SR04 -1, // SR04 Ech/RXo pin + AGPIO(GPIO_SR04_TRIG) + AGMAX(MAX_SR04), // SR04 Tri/TXgger pin + AGPIO(GPIO_SR04_ECHO) + AGMAX(MAX_SR04), // SR04 Ech/RXo pin #endif #ifdef USE_ME007 - AGPIO(GPIO_ME007_TRIG), // ME007 Trigger pin (xsns_23_me007.ino) - AGPIO(GPIO_ME007_RX), // ME007 Rx pin (xsns_23_me007.ino) + AGPIO(GPIO_ME007_TRIG), // ME007 Trigger pin (xsns_23_me007.ino) + AGPIO(GPIO_ME007_RX), // ME007 Rx pin (xsns_23_me007.ino) #endif #ifdef USE_TM1638 - AGPIO(GPIO_TM1638CLK), // TM1638 Clock - AGPIO(GPIO_TM1638DIO), // TM1638 Data I/O - AGPIO(GPIO_TM1638STB), // TM1638 Strobe + AGPIO(GPIO_TM1638CLK), // TM1638 Clock + AGPIO(GPIO_TM1638DIO), // TM1638 Data I/O + AGPIO(GPIO_TM1638STB), // TM1638 Strobe #endif #ifdef USE_HX711 - AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock - AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data + AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock + AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data #endif #ifdef USE_TFMINIPLUS - AGPIO(GPIO_TFMINIPLUS_TX), // TFmini Plus TX pin - AGPIO(GPIO_TFMINIPLUS_RX), // TFmini Plus RX pin + AGPIO(GPIO_TFMINIPLUS_TX), // TFmini Plus TX pin + AGPIO(GPIO_TFMINIPLUS_RX), // TFmini Plus RX pin #endif /*-------------------------------------------------------------------------------------------*\ @@ -897,109 +897,109 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_ENERGY_SENSOR #ifdef USE_HLW8012 - AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) - AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) - AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current - AGPIO(GPIO_HLW_CF), // HLW8012 CF power - AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power + AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) + AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) + AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current + AGPIO(GPIO_HLW_CF), // HLW8012 CF power + AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power #endif #if defined(USE_I2C) && defined(USE_ADE7880) - AGPIO(GPIO_ADE7880_IRQ) + 2 -1, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) + AGPIO(GPIO_ADE7880_IRQ) + AGMAX(2), // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) #endif #ifdef USE_ADE7953 #if defined(USE_I2C) || defined(USE_SPI) - AGPIO(GPIO_ADE7953_IRQ) + 6 -1, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) - AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset + AGPIO(GPIO_ADE7953_IRQ) + AGMAX(6), // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) + AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset #ifdef USE_SPI - AGPIO(GPIO_ADE7953_CS) + 2 -1, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) + AGPIO(GPIO_ADE7953_CS) + AGMAX(2), // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) #endif // USE_SPI #endif // USE_I2C or USE_SPI #endif // USE_ADE7953 #ifdef USE_CSE7761 - AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) - AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761 -1, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) + AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) + AGPIO(GPIO_CSE7761_RX) + AGMAX(MAX_CSE7761), // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) #endif #ifdef USE_CSE7766 - AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) - AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) + AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) + AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) #endif #ifdef USE_MCP39F501 - AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) - AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) - AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) + AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) #endif - AGPIO(GPIO_NRG_MBS_TX_ENA), // Generic Energy Modbus Transmit Enable + AGPIO(GPIO_NRG_MBS_TX_ENA), // Generic Energy Modbus Transmit Enable #if defined(USE_PZEM004T) || defined(USE_PZEM_AC) || defined(USE_PZEM_DC) - AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface + AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface #endif #ifdef USE_PZEM004T - AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface + AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface #endif #ifdef USE_PZEM_AC - AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface + AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface #endif #ifdef USE_PZEM_DC - AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface + AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface #endif #ifdef USE_MODBUS_ENERGY - AGPIO(GPIO_NRG_MBS_TX), // Generic Energy Modbus device + AGPIO(GPIO_NRG_MBS_TX), // Generic Energy Modbus device AGPIO(GPIO_NRG_MBS_RX), #endif #ifdef USE_SDM120 - AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface - AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface + AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface + AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface #endif #ifdef USE_SDM630 - AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface - AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface + AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface + AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface #endif #ifdef USE_DDS2382 - AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface - AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface + AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface + AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface #endif #ifdef USE_DDSU666 - AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface - AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface + AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface + AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface #endif // USE_DDSU666 #ifdef USE_SOLAX_X1 - AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin - AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin - AGPIO(GPIO_SOLAXX1_RTS), // Solax Inverter RTS pin + AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin + AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin + AGPIO(GPIO_SOLAXX1_RTS), // Solax Inverter RTS pin #endif // USE_SOLAX_X1 #ifdef USE_LE01MR - AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin - AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin + AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin + AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin #endif // USE_LE01MR #ifdef ESP32 #ifdef USE_BL0906 - AGPIO(GPIO_BL0906_RX) + MAX_BL0906_RX -1, // BL0906 Serial interface (Athom EM6) + AGPIO(GPIO_BL0906_RX) + AGMAX(MAX_BL0906_RX), // BL0906 Serial interface (Athom EM6) #endif // USE_BL0906 #endif // ESP32 #if defined(USE_BL0940) || defined(USE_BL09XX) - AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) - AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface - AGPIO(GPIO_BL0942_RX) + MAX_BL0942_RX -1, // BL0942 Serial interface + AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) + AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface + AGPIO(GPIO_BL0942_RX) + AGMAX(MAX_BL0942_RX), // BL0942 Serial interface #endif #ifdef USE_IEM3000 - AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface - AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface + AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface + AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface #endif #ifdef USE_WE517 - AGPIO(GPIO_WE517_TX), // WE517 Serial interface - AGPIO(GPIO_WE517_RX), // WE517 Serial interface + AGPIO(GPIO_WE517_TX), // WE517 Serial interface + AGPIO(GPIO_WE517_RX), // WE517 Serial interface #endif #ifdef USE_SDM72 - AGPIO(GPIO_SDM72_TX), // SDM72 Serial interface - AGPIO(GPIO_SDM72_RX), // SDM72 Serial interface + AGPIO(GPIO_SDM72_TX), // SDM72 Serial interface + AGPIO(GPIO_SDM72_RX), // SDM72 Serial interface #endif AGPIO(GPIO_ZEROCROSS), #ifdef USE_SDM230 - AGPIO(GPIO_SDM230_TX), // SDM230 Serial interface - AGPIO(GPIO_SDM230_RX), // SDM230 Serial interface + AGPIO(GPIO_SDM230_TX), // SDM230 Serial interface + AGPIO(GPIO_SDM230_RX), // SDM230 Serial interface #endif #ifdef USE_BL6523 - AGPIO(GPIO_BL6523_TX), // BL6523 based Watt meter Serial interface - AGPIO(GPIO_BL6523_RX), // BL6523 based Watt meter Serial interface + AGPIO(GPIO_BL6523_TX), // BL6523 based Watt meter Serial interface + AGPIO(GPIO_BL6523_RX), // BL6523 based Watt meter Serial interface #endif #endif // USE_ENERGY_SENSOR @@ -1008,134 +1008,134 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #ifdef USE_SERIAL_BRIDGE - AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface - AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface + AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface + AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface #endif #ifdef USE_MODBUS_BRIDGE - AGPIO(GPIO_MBR_TX_ENA), // Modbus Bridge Serial interface - AGPIO(GPIO_MBR_TX), // Modbus Bridge Serial interface - AGPIO(GPIO_MBR_RX), // Modbus Bridge Serial interface + AGPIO(GPIO_MBR_TX_ENA), // Modbus Bridge Serial interface + AGPIO(GPIO_MBR_TX), // Modbus Bridge Serial interface + AGPIO(GPIO_MBR_RX), // Modbus Bridge Serial interface #endif #ifdef USE_TCP_BRIDGE - AGPIO(GPIO_TCP_TX), // TCP Serial bridge - AGPIO(GPIO_TCP_RX), // TCP Serial bridge - AGPIO(GPIO_TCP_TX_EN), // TCP Serial bridge EN + AGPIO(GPIO_TCP_TX), // TCP Serial bridge + AGPIO(GPIO_TCP_RX), // TCP Serial bridge + AGPIO(GPIO_TCP_TX_EN), // TCP Serial bridge EN #endif #ifdef USE_ZIGBEE - AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RST) + 2 -1, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode + AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RST) + AGMAX(2), // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode #endif #ifdef USE_MHZ19 - AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface - AGPIO(GPIO_MHZ_RXD), // MH-Z19 Serial interface + AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface + AGPIO(GPIO_MHZ_RXD), // MH-Z19 Serial interface #endif #ifdef USE_HC8 - AGPIO(GPIO_HC8_RXD), // HC8 Serial interface + AGPIO(GPIO_HC8_RXD), // HC8 Serial interface #endif #ifdef USE_SENSEAIR - AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface - AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface + AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface + AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface #endif #ifdef USE_NOVA_SDS - AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface - AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface + AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface + AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface #endif #ifdef USE_HPMA - AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface - AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface + AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface + AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface #endif #ifdef USE_PMS5003 - AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface - AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface + AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface + AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface #endif #ifdef USE_VINDRIKTNING - AGPIO(GPIO_VINDRIKTNING_RX), // Ikea Vindriktning + AGPIO(GPIO_VINDRIKTNING_RX), // Ikea Vindriktning #endif #ifdef USE_HM330X - AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low) + AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low) #endif #if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) || defined(USE_WS2300_WIND_SENSOR) - AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin + AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin #endif -#ifdef USE_WINDMETER // xsns_68_windmeter.ino +#ifdef USE_WINDMETER AGPIO(GPIO_WINDMETER_SPEED), #endif -#ifdef USE_MP3_PLAYER // xdrv_14_mp3.ino - AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface - AGPIO(GPIO_MP3_DFR562_BUSY), // RB-DFR-562, DFPlayer Mini MP3 Player optional Busy flag +#ifdef USE_MP3_PLAYER + AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface + AGPIO(GPIO_MP3_DFR562_BUSY), // RB-DFR-562, DFPlayer Mini MP3 Player optional Busy flag #endif -#ifdef USE_AZ7798 // xsns_38_az7798 - AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface - AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface +#ifdef USE_AZ7798 + AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface + AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface #endif -#ifdef USE_PN532_HSU // xsns_40_pn532.ino - AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx - AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx +#ifdef USE_PN532_HSU + AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx + AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx #endif -#ifdef USE_TASMOTA_CLIENT // xdrv_31_tasmota_client.ino - AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX - AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX - AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset - AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted +#ifdef USE_TASMOTA_CLIENT + AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX + AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX + AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset + AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted #endif -#ifdef USE_RDM6300 // xsns_51_rdm6300.ino +#ifdef USE_RDM6300 AGPIO(GPIO_RDM6300_RX), #endif -#ifdef USE_IBEACON // xsns_52_ibeacon.ino +#ifdef USE_IBEACON AGPIO(GPIO_IBEACON_TX), AGPIO(GPIO_IBEACON_RX), #endif -#ifdef USE_GPS // xsns_60_gps.ino - AGPIO(GPIO_GPS_TX), // GPS serial interface - AGPIO(GPIO_GPS_RX), // GPS serial interface +#ifdef USE_GPS + AGPIO(GPIO_GPS_TX), // GPS serial interface + AGPIO(GPIO_GPS_RX), // GPS serial interface #endif -#ifdef USE_HM10 // xsns_62_mi_hm10.ino - AGPIO(GPIO_HM10_TX), // HM10 serial interface - AGPIO(GPIO_HM10_RX), // HM10 serial interface +#ifdef USE_HM10 + AGPIO(GPIO_HM10_TX), // HM10 serial interface + AGPIO(GPIO_HM10_RX), // HM10 serial interface #endif -#ifdef USE_OPENTHERM // xsns_69_opentherm.ino +#ifdef USE_OPENTHERM AGPIO(GPIO_BOILER_OT_TX), AGPIO(GPIO_BOILER_OT_RX), #endif -#ifdef USE_AS608 // xsns_79_as608.ino +#ifdef USE_AS608 AGPIO(GPIO_AS608_TX), AGPIO(GPIO_AS608_RX), #endif -#ifdef USE_GM861 // xsns_107_gm861.ino +#ifdef USE_GM861 AGPIO(GPIO_GM861_TX), AGPIO(GPIO_GM861_RX), #endif -#ifdef USE_HRG15 // xsns_90_hrg15.ino +#ifdef USE_HRG15 AGPIO(GPIO_HRG15_TX), AGPIO(GPIO_HRG15_RX), #endif -#ifdef USE_CM110x // xsns_95_cm110x.ino - AGPIO(GPIO_CM11_TXD), // CM110x Serial interface - AGPIO(GPIO_CM11_RXD), // CM110x Serial interface +#ifdef USE_CM110x + AGPIO(GPIO_CM11_TXD), // CM110x Serial interface + AGPIO(GPIO_CM11_RXD), // CM110x Serial interface #endif -#ifdef USE_LD2410 // xsns_102_ld2410.ino - AGPIO(GPIO_LD2410_TX), // HLK-LD2410 Serial interface - AGPIO(GPIO_LD2410_RX), // HLK-LD2410 Serial interface +#ifdef USE_LD2410 + AGPIO(GPIO_LD2410_TX), // HLK-LD2410 Serial interface + AGPIO(GPIO_LD2410_RX), // HLK-LD2410 Serial interface #endif -#ifdef USE_LD2410S // xsns_102_ld2410s.ino - AGPIO(GPIO_LD2410S_TX), // HLK-LD2410S Serial interface - AGPIO(GPIO_LD2410S_RX), // HLK-LD2410S Serial interface +#ifdef USE_LD2410S + AGPIO(GPIO_LD2410S_TX), // HLK-LD2410S Serial interface + AGPIO(GPIO_LD2410S_RX), // HLK-LD2410S Serial interface #endif -#ifdef USE_LOX_O2 // xsns_105_lox_o2.ino - AGPIO(GPIO_LOX_O2_RX), // LuminOx Oxygen Sensor LOX-O2 Serial interface +#ifdef USE_LOX_O2 + AGPIO(GPIO_LOX_O2_RX), // LuminOx Oxygen Sensor LOX-O2 Serial interface #endif #ifdef USE_LORAWAN_RN2XX3 AGPIO(GPIO_RN2XX3_TX), AGPIO(GPIO_RN2XX3_RX), - AGPIO(GPIO_RN2XX3_RST), // RN2XX3 LoRaWan node Serial interface + AGPIO(GPIO_RN2XX3_RST), // RN2XX3 LoRaWan node Serial interface #endif #ifdef USE_LORAWAN_ASR650X AGPIO(GPIO_ASR650X_TX), - AGPIO(GPIO_ASR650X_RX), // ASR650X LoRaWan node Serial interface + AGPIO(GPIO_ASR650X_RX), // ASR650X LoRaWan node Serial interface #endif -#ifdef USE_WOOLIIS // xsns_115_wooliis.ino - AGPIO(GPIO_WOOLIIS_RX), // Wooliis Battery capacity monitor Serial interface +#ifdef USE_WOOLIIS + AGPIO(GPIO_WOOLIIS_RX), // Wooliis Battery capacity monitor Serial interface #endif /*-------------------------------------------------------------------------------------------*\ @@ -1147,27 +1147,27 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MGC3130_RESET), #endif #ifdef USE_MAX31855 - AGPIO(GPIO_MAX31855CS) + MAX_MAX31855S -1, //MAX31855 Serial interface - AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface - AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855CS) + AGMAX(MAX_MAX31855S), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface #endif #ifdef USE_HRE AGPIO(GPIO_HRE_CLOCK), AGPIO(GPIO_HRE_DATA), #endif #ifdef USE_A4988_STEPPER - AGPIO(GPIO_A4988_DIR), // A4988 direction pin - AGPIO(GPIO_A4988_STP), // A4988 step pin + AGPIO(GPIO_A4988_DIR), // A4988 direction pin + AGPIO(GPIO_A4988_STP), // A4988 step pin // folowing are not mandatory - AGPIO(GPIO_A4988_ENA), // A4988 enabled pin - AGPIO(GPIO_A4988_MS1) + MAX_A4988_MSS -1, // A4988 microstep pin1 to pin3 + AGPIO(GPIO_A4988_ENA), // A4988 enabled pin + AGPIO(GPIO_A4988_MS1) + AGMAX(MAX_A4988_MSS), // A4988 microstep pin1 to pin3 #endif #ifdef USE_DEEPSLEEP AGPIO(GPIO_DEEPSLEEP), #endif #ifdef USE_KEELOQ - AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX - AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX + AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX + AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX #endif #ifdef USE_HRXL AGPIO(GPIO_HRXL_RX), @@ -1176,48 +1176,48 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_DYP_RX), #endif #ifdef USE_AS3935 - AGPIO(GPIO_AS3935), // AS3935 IRQ Pin + AGPIO(GPIO_AS3935), // AS3935 IRQ Pin #endif #ifdef USE_TELEINFO AGPIO(GPIO_TELEINFO_RX), AGPIO(GPIO_TELEINFO_ENABLE), #endif #ifdef USE_MIEL_HVAC - AGPIO(GPIO_MIEL_HVAC_TX), // Mitsubishi Electric HVAC TX pin - AGPIO(GPIO_MIEL_HVAC_RX), // Mitsubishi Electric HVAC RX pin + AGPIO(GPIO_MIEL_HVAC_TX), // Mitsubishi Electric HVAC TX pin + AGPIO(GPIO_MIEL_HVAC_RX), // Mitsubishi Electric HVAC RX pin #endif #ifdef USE_TUYAMCUBR AGPIO(GPIO_TUYAMCUBR_TX), AGPIO(GPIO_TUYAMCUBR_RX), #endif #ifdef USE_WIEGAND - AGPIO(GPIO_WIEGAND_D0), // Date line D0 of Wiegand devices - AGPIO(GPIO_WIEGAND_D1), // Date line D1 of Wiegand devices + AGPIO(GPIO_WIEGAND_D0), // Data line D0 of Wiegand devices + AGPIO(GPIO_WIEGAND_D1), // Data line D1 of Wiegand devices #endif #ifdef USE_NEOPOOL - AGPIO(GPIO_NEOPOOL_TX), // Sugar Valley RS485 Interface - AGPIO(GPIO_NEOPOOL_RX), // Sugar Valley RS485 Interface + AGPIO(GPIO_NEOPOOL_TX), // Sugar Valley RS485 Interface + AGPIO(GPIO_NEOPOOL_RX), // Sugar Valley RS485 Interface #endif #ifdef USE_PROJECTOR_CTRL - AGPIO(GPIO_PROJECTOR_CTRL_TX), // LCD/DLP Projector Serial Control - AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control + AGPIO(GPIO_PROJECTOR_CTRL_TX), // LCD/DLP Projector Serial Control + AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control #endif #if defined(USE_VL53L0X) or defined (USE_VL53L1X) - AGPIO(GPIO_VL53LXX_XSHUT1) + VL53LXX_MAX_SENSORS -1, // When using multiple VL53LXX. + AGPIO(GPIO_VL53LXX_XSHUT1) + AGMAX(VL53LXX_MAX_SENSORS), // When using multiple VL53LXX. #endif #ifdef USE_FLOWRATEMETER - AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER -1, // Flow meter Pin + AGPIO(GPIO_FLOWRATEMETER_IN) + AGMAX(MAX_FLOWRATEMETER), // Flow meter Pin #endif #ifdef USE_SHIFT595 - AGPIO(GPIO_SHIFT595_SRCLK), // 74x595 shift register + AGPIO(GPIO_SHIFT595_SRCLK), // 74x595 shift register AGPIO(GPIO_SHIFT595_RCLK), AGPIO(GPIO_SHIFT595_OE), AGPIO(GPIO_SHIFT595_SER), #endif #if defined (ESP32) && defined(USE_DINGTIAN_RELAY) - AGPIO(GPIO_DINGTIAN_CLK) + MAX_DINGTIAN_SHIFT -1, // Dingtian Relay board - 8,16,24 or 32 relays & inputs + AGPIO(GPIO_DINGTIAN_CLK) + AGMAX(MAX_DINGTIAN_SHIFT), // Dingtian Relay board - 8,16,24 or 32 relays & inputs AGPIO(GPIO_DINGTIAN_SDI), AGPIO(GPIO_DINGTIAN_Q7), AGPIO(GPIO_DINGTIAN_PL), @@ -1226,12 +1226,12 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #ifdef USE_MAGIC_SWITCH - AGPIO(GPIO_MAGIC_SWITCH) + MAX_MAGIC_SWITCH_MODES -1, + AGPIO(GPIO_MAGIC_SWITCH) + AGMAX(MAX_MAGIC_SWITCH_MODES), #endif -#ifdef USE_PIPSOLAR // xdrv_92_pipsolar.ino - AGPIO(GPIO_PIPSOLAR_TX), // pipsolar inverter Serial interface - AGPIO(GPIO_PIPSOLAR_RX), // pipsolar inverter Serial interface +#ifdef USE_PIPSOLAR + AGPIO(GPIO_PIPSOLAR_TX), // pipsolar inverter Serial interface + AGPIO(GPIO_PIPSOLAR_RX), // pipsolar inverter Serial interface #endif /*-------------------------------------------------------------------------------------------*\ @@ -1240,7 +1240,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef ESP32 #if CONFIG_IDF_TARGET_ESP32 - AGPIO(GPIO_HALLEFFECT) + 2 -1, // Hall effect sensor connected to GPIO36 and 39 + AGPIO(GPIO_HALLEFFECT) + AGMAX(2), // Hall effect sensor connected to GPIO36 and 39 #endif // CONFIG_IDF_TARGET_ESP32 #ifdef USE_WEBCAM AGPIO(GPIO_WEBCAM_PWDN), @@ -1248,41 +1248,41 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_WEBCAM_XCLK), AGPIO(GPIO_WEBCAM_SIOD), AGPIO(GPIO_WEBCAM_SIOC), - AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA -1, + AGPIO(GPIO_WEBCAM_DATA) + AGMAX(MAX_WEBCAM_DATA), AGPIO(GPIO_WEBCAM_VSYNC), AGPIO(GPIO_WEBCAM_HREF), AGPIO(GPIO_WEBCAM_PCLK), AGPIO(GPIO_WEBCAM_PSCLK), - AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD -1, + AGPIO(GPIO_WEBCAM_HSD) + AGMAX(MAX_WEBCAM_HSD), AGPIO(GPIO_WEBCAM_PSRCS), #endif // USE_WEBCAM #ifdef USE_ETHERNET AGPIO(GPIO_ETH_PHY_POWER), AGPIO(GPIO_ETH_PHY_MDC), - AGPIO(GPIO_ETH_PHY_MDIO), // Ethernet + AGPIO(GPIO_ETH_PHY_MDIO), // Ethernet #endif // USE_ETHERNET #ifdef USE_BIOPDU - AGPIO(GPIO_BIOPDU_PZEM0XX_TX), // Biomine BioPDU pins + AGPIO(GPIO_BIOPDU_PZEM0XX_TX), // Biomine BioPDU pins AGPIO(GPIO_BIOPDU_PZEM016_RX), - AGPIO(GPIO_BIOPDU_BIT) + 3 -1, + AGPIO(GPIO_BIOPDU_BIT) + AGMAX(3), #endif /*-------------------------------------------------------------------------------------------*\ * ESP32 multiple Analog / Digital converter inputs \*-------------------------------------------------------------------------------------------*/ - AGPIO(GPIO_ADC_INPUT) + MAX_ADCS -1, // Analog inputs - AGPIO(GPIO_ADC_TEMP) + MAX_ADCS -1, // Thermistor - AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS -1, // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS -1, // Button - AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS -1, - AGPIO(GPIO_ADC_RANGE) + MAX_ADCS -1, // Range - AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS -1, // Current - AGPIO(GPIO_ADC_JOY) + MAX_ADCS -1, // Joystick - AGPIO(GPIO_ADC_PH) + MAX_ADCS -1, // Analog PH Sensor - AGPIO(GPIO_ADC_MQ) + MAX_ADCS -1, // Analog MQ Sensor - AGPIO(GPIO_ADC_VOLTAGE) + MAX_ADCS -1, // Voltage - AGPIO(GPIO_ADC_CURRENT) + MAX_ADCS -1, // Current + AGPIO(GPIO_ADC_INPUT) + AGMAX(MAX_ADCS), // Analog inputs + AGPIO(GPIO_ADC_TEMP) + AGMAX(MAX_ADCS), // Thermistor + AGPIO(GPIO_ADC_LIGHT) + AGMAX(MAX_ADCS), // Light sensor + AGPIO(GPIO_ADC_BUTTON) + AGMAX(MAX_KEYS), // Button + AGPIO(GPIO_ADC_BUTTON_INV) + AGMAX(MAX_KEYS), + AGPIO(GPIO_ADC_RANGE) + AGMAX(MAX_ADCS), // Range + AGPIO(GPIO_ADC_CT_POWER) + AGMAX(MAX_ADCS), // Current + AGPIO(GPIO_ADC_JOY) + AGMAX(MAX_ADCS), // Joystick + AGPIO(GPIO_ADC_PH) + AGMAX(MAX_ADCS), // Analog PH Sensor + AGPIO(GPIO_ADC_MQ) + AGMAX(MAX_ADCS), // Analog MQ Sensor + AGPIO(GPIO_ADC_VOLTAGE) + AGMAX(MAX_ADCS), // Voltage + AGPIO(GPIO_ADC_CURRENT) + AGMAX(MAX_ADCS), // Current #endif // ESP32 }; @@ -1292,19 +1292,19 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef ESP8266 const uint16_t kAdcNiceList[] PROGMEM = { - GPIO_NONE, // Not used - AGPIO(GPIO_ADC_INPUT), // Analog inputs - AGPIO(GPIO_ADC_TEMP), // Thermistor - AGPIO(GPIO_ADC_LIGHT), // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS -1, // Button - AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS -1, - AGPIO(GPIO_ADC_RANGE), // Range - AGPIO(GPIO_ADC_CT_POWER), // Current - AGPIO(GPIO_ADC_JOY), // Joystick - AGPIO(GPIO_ADC_PH), // Analog PH Sensor - AGPIO(GPIO_ADC_MQ), // Analog MQ Sensor - AGPIO(GPIO_ADC_VOLTAGE), // Voltage - AGPIO(GPIO_ADC_CURRENT), // Current + GPIO_NONE, // Not used + AGPIO(GPIO_ADC_INPUT), // Analog inputs + AGPIO(GPIO_ADC_TEMP), // Thermistor + AGPIO(GPIO_ADC_LIGHT), // Light sensor + AGPIO(GPIO_ADC_BUTTON) + AGMAX(MAX_KEYS), // Button + AGPIO(GPIO_ADC_BUTTON_INV) + AGMAX(MAX_KEYS), + AGPIO(GPIO_ADC_RANGE), // Range + AGPIO(GPIO_ADC_CT_POWER), // Current + AGPIO(GPIO_ADC_JOY), // Joystick + AGPIO(GPIO_ADC_PH), // Analog PH Sensor + AGPIO(GPIO_ADC_MQ), // Analog MQ Sensor + AGPIO(GPIO_ADC_VOLTAGE), // Voltage + AGPIO(GPIO_ADC_CURRENT), // Current }; #endif // ESP8266 diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index e1ed6a7da..2c25cdd28 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -1805,7 +1805,7 @@ void CmndGpio(void) if (ValidGPIO(XdrvMailbox.index, template_gp.io[XdrvMailbox.index]) && (XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < AGPIO(GPIO_SENSOR_END))) { bool present = false; for (uint32_t i = 0; i < nitems(kGpioNiceList); i++) { - uint32_t midx = pgm_read_word(kGpioNiceList + i); + uint32_t midx = pgm_read_word(&kGpioNiceList[i]); uint32_t max_midx = ((midx & 0x001F) > 0) ? midx : midx +1; if ((XdrvMailbox.payload >= (midx & 0xFFE0)) && (XdrvMailbox.payload < max_midx)) { present = true; @@ -1843,7 +1843,7 @@ void CmndGpio(void) uint32_t sensor_name_idx = BGPIO(sensor_type); uint32_t nice_list_search = sensor_type & 0xFFE0; for (uint32_t j = 0; j < nitems(kGpioNiceList); j++) { - uint32_t nls_idx = pgm_read_word(kGpioNiceList + j); + uint32_t nls_idx = pgm_read_word(&kGpioNiceList[j]); if (((nls_idx & 0xFFE0) == nice_list_search) && ((nls_idx & 0x001F) > 0)) { snprintf_P(sindex, sizeof(sindex), PSTR("%d"), (sensor_type & 0x001F) +1); break; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 856c9a46d..3bc5634c5 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1932,7 +1932,7 @@ void WSContentSendNiceLists(uint32_t option) { if (option && (1 == i)) { WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), PSTR(D_SENSOR_USER)); // }2'255'>User}3 } - uint32_t ridx = pgm_read_word(kGpioNiceList + i) & 0xFFE0; + uint32_t ridx = pgm_read_word(&kGpioNiceList[i]) & 0xFFE0; uint32_t midx = BGPIO(ridx); WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames)); } @@ -1942,7 +1942,7 @@ void WSContentSendNiceLists(uint32_t option) { uint32_t midx; bool first_done = false; for (uint32_t i = 0; i < nitems(kGpioNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; - midx = pgm_read_word(kGpioNiceList + i); + midx = pgm_read_word(&kGpioNiceList[i]); if (midx & 0x001F) { if (first_done) { WSContentSend_P(PSTR(",")); } WSContentSend_P(PSTR("%d"), midx); From ae7cba2f136e526775a2db891aee9be8eeffa5d6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:31:21 +0100 Subject: [PATCH 146/205] Add support for TM1640 based IoTTimer by Stefan Oskamp (#21376) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/my_user_config.h | 14 +- .../tasmota_xdrv_driver/xdrv_13_display.ino | 2 +- .../tasmota_xdsp_display/xdsp_13_tm1640.ino | 779 ++++++++++++++++++ 5 files changed, 790 insertions(+), 7 deletions(-) create mode 100644 tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cef53e8b..c6a4c85bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ## [14.3.0.7] ### Added +- Support for TM1640 based IoTTimer by Stefan Oskamp (#21376) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ee2aaedf1..f36832a88 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -130,6 +130,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Support for HLK-LD2410S 24GHz smart wave motion sensor [#22253](https://github.com/arendst/Tasmota/issues/22253) - Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) - Support for MS5837 pressure and temperature sensor [#22376](https://github.com/arendst/Tasmota/issues/22376) +- Support for TM1640 based IoTTimer by Stefan Oskamp [#21376](https://github.com/arendst/Tasmota/issues/21376) - HLK-LD2410 Engineering mode [#21880](https://github.com/arendst/Tasmota/issues/21880) - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index d6822db2f..5af1f9aaa 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -775,7 +775,7 @@ #define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module #define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module #define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C 0x70-0x77) (<+11k code) -// #define USE_DISPLAY_SEVENSEG_COMMON_ANODE // Enable support for common anode sevenseg displays +// #define USE_DISPLAY_SEVENSEG_COMMON_ANODE // Enable support for common anode sevenseg displays // Multiple sevenseg displays are logically arranged vertically with MTX_ADDRESS1 at y=0, // MTX_ADDRESS2 at y=1, up to MTX_ADDRESS8 at y=7 // Command: DisplayText [yn]8888 @@ -783,7 +783,7 @@ // Each segment may be address Command: DisplayText [xn]m // where n is 0..4 (4 digits and middle :) and m is decimal for bitmap of which segment to turn on. // Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf - // #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays +// #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays // #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D) // #define USE_DISPLAY_TM1650 // [DisplayModel 20] [I2cDriver74] Enable TM1650 display (I2C addresses 0x24 - 0x27 and 0x34 - 0x37) // #define USE_DT_VARS // Display variables that are exposed in JSON MQTT strings e.g. in TelePeriod messages. @@ -793,10 +793,12 @@ #endif // USE_I2C -// #define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code) -// #define USE_DISPLAY_TM1637 // [DisplayModel 15] Enable TM1637 Seven Segment Display Module (4-6 digits) -// #define USE_DISPLAY_MAX7219 // [DisplayModel 15] Enable MAX7219 Seven Segment Display Module (8 digits) -// #define USE_DISPLAY_MAX7219_MATRIX // [DisplayModel 19] Enable MAX7219 8x8 Matrix Display +//#define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code) +// #define USE_DISPLAY_TM1637 // [DisplayModel 15] Enable TM1637 Seven Segment Display Module (4-6 digits) +// #define USE_DISPLAY_MAX7219 // [DisplayModel 15] Enable MAX7219 Seven Segment Display Module (8 digits) +// #define USE_DISPLAY_MAX7219_MATRIX // [DisplayModel 19] Enable MAX7219 8x8 Matrix Display +// #define USE_DISPLAY_TM1640 // [DisplayModel 13] Enable TM1640 module Seven Segment Display Module (stub) +// #define USE_IOTTIMER // Enable TM1640 based IotTimer // -- Universal Display Driver --------------------------------- // #define USE_UNIVERSAL_DISPLAY // New universal display driver for both I2C and SPI diff --git a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino index a7afe6d47..33a445527 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino @@ -2169,7 +2169,7 @@ void CmndDisplayText(void) { void CmndDisplayClear(void) { DisplayClear(); - ResponseCmndChar(XdrvMailbox.data); + ResponseCmndDone(); } void CmndDisplayNumber(void) { diff --git a/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino b/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino new file mode 100644 index 000000000..dd1d868d8 --- /dev/null +++ b/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino @@ -0,0 +1,779 @@ +/* + xdsp_13_tm1640.ino - TM1640B LED display controller support for Tasmota + + Copyright (C) 2024 Stefan Oskamp + + 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_DISPLAY +#ifdef USE_DISPLAY_TM1640 +/*********************************************************************************************\ + This driver enables the display of the current time, numbers (both integers and floats) and + basic text on the IoTTimer clock. + + Template {"NAME":"IoTTimer Lo","GPIO":[32,33,0,34,3872,1312,0,0,10944,10912,640,480,608,4768],"FLAG":0,"BASE":18} + + In addition, it is possible to set brightness (seven levels plus off) and clear the display. + + To use, compile Tasmota with USE_DISPLAY, USE_DISPLAY_TM1640 and USE_IOTTIMER, or build the tasmota-display + firmware. + + Either use following template: + Template {"NAME":"IoTTimer Lo","GPIO":[32,33,0,34,3872,1312,0,0,10944,10912,640,480,608,4768],"FLAG":0,"BASE":18} + + or configure manually: + For the IoTTimer clock assign the pins as follows from Tasmota's GUI: + + GPIO12 --> "TM1640 DIN" + GPIO13 --> "TM1640 CLK" + + Once the GPIO configuration is saved and the ESP8266/ESP32 module restarts, set the Display + Model to 13 and Display Mode to 0 using the command "Backlog DisplayModel 13 ; DisplayMode 0;" + Before using it, set the Display Type to 1 (for IOTTIMER) using the "DisplayType 1" command. + + After the ESP8266 restarts again, turn ON the display with the command "Power 1" + + Now, the following "Display" commands can be used: + + + DisplayClear + + Clears the display, command: "DisplayClear" + + + DisplayFloat num + + Clears and then displays float (with decimal point) command e.g., "DisplayFloat 12.3" + See function description below for more details. + + + DisplayFloatNC num + + Same as DisplayFloatNC + + + DisplayClock 1|2|3|4 + + Displays a clock. + Commands "DisplayClock 1" // 12 hr format + "DisplayClock 2" // 24 hr format + "DisplayClock 3" // 12-hour without seconds + "DisplayClock 4" // 24-hour without seconds + + +In addition, if you compile using USE_DISPLAY_MODES1TO5, setting DisplayMode to 1 shows the time, +setting it to 2 shows the date and setting it to 3 alternates between time and date (using "DisplayRefresh [1..7]" +for the time and seconds you want to show the time before displaying the date) + +\*********************************************************************************************/ + +#define XDSP_13 13 + +#define TM1640_CMD_DATA_AUTO 0x40 +#define TM1640_CMD_DATA_FIXED 0x44 +#define TM1640_CMD_DISPLAY 0x80 +#define TM1640_CMD_ADDRESS 0xC0 + +#define TM1640_CLOCK_DELAY 1 // uSec + +#define LEVEL_MIN 0 +#define LEVEL_MAX 100 + +enum tm1640_display_options_types { + TM1640_DEFAULT, + TM1640_IOTTIMER // IOTTIMER WiFi clock +}; + +typedef struct Tm1640_t { + int8_t clock_pin; + int8_t data_pin; + bool show_clock; + bool clock_24; + bool clock_seconds; +} Tm1640_t; + +Tm1640_t* Tm1640 = nullptr; + +/*********************************************************************************************\ + * TM1640 low level functions +\*********************************************************************************************/ + +void TM1640Start (void) { + digitalWrite(Tm1640->data_pin, LOW); + digitalWrite(Tm1640->clock_pin, LOW); + delayMicroseconds(TM1640_CLOCK_DELAY); +} + +void TM1640Stop (void) { + digitalWrite(Tm1640->clock_pin, HIGH); + digitalWrite(Tm1640->data_pin, HIGH); + delayMicroseconds(TM1640_CLOCK_DELAY); +} + +void TM1640Send(uint8_t data) { + for (uint32_t i = 0; i < 8; i++) { // 8 bits + digitalWrite(Tm1640->data_pin, data & 1 ? HIGH : LOW); + delayMicroseconds(TM1640_CLOCK_DELAY); + data >>= 1; + digitalWrite(Tm1640->clock_pin, HIGH); + delayMicroseconds(TM1640_CLOCK_DELAY); + digitalWrite(Tm1640->clock_pin, LOW); + delayMicroseconds(TM1640_CLOCK_DELAY); + } + digitalWrite(Tm1640->data_pin, LOW); + delayMicroseconds(TM1640_CLOCK_DELAY); +} + +void TM1640SendData(uint8_t address, uint8_t data) { + // First, send data command using FIXED addressing: + TM1640Start(); + TM1640Send(TM1640_CMD_DATA_FIXED); + TM1640Stop(); + // Then, send address and one data byte: + TM1640Start(); + TM1640Send(TM1640_CMD_ADDRESS | address); + TM1640Send(data); + TM1640Stop(); +} + +void TM1640SendDataArray(uint8_t address, uint8_t *data, uint8_t count) { + // First, send data command using AUTO addressing: + TM1640Start(); + TM1640Send(TM1640_CMD_DATA_AUTO); + TM1640Stop(); + // Then, send address and all data bytes: + TM1640Start(); + TM1640Send(TM1640_CMD_ADDRESS | address); + while (count-- > 0) { + TM1640Send(*data++); + } + TM1640Stop(); +} + +void TM1640SetBrightness(uint8_t level) { + // level can be 0 to 8. + // 0 means off + // + // Other levels are mapped to TM1640 levels 0 ... 7 + // The mapping to the PWM level is non-linear, according to the data sheet + // level | TM1640 | PWM + // 1 | 0 | 1/16 + // 2 | 1 | 2/16 + // 3 | 2 | 4/16 + // 4 | 3 | 10/16 + // 5 | 4 | 11/16 + // 6 | 5 | 12/16 + // 7 | 6 | 13/16 + // 8 | 7 | 14/16 + uint8_t cmd = TM1640_CMD_DISPLAY | (level > 0 ? 0x8 : 0) | ((level - 1) % 8); + TM1640Start(); + TM1640Send (cmd); + TM1640Stop(); +} + +/*********************************************************************************************\ +* Init function +\*********************************************************************************************/ + +void TM1640Init(void) { + if (PinUsed(GPIO_TM1640CLK) && PinUsed(GPIO_TM1640DIN)) { + Tm1640 = (Tm1640_t*)calloc(sizeof(Tm1640_t), 1); // Need calloc to reset registers to 0/false + if (nullptr == Tm1640) { return; } + + Tm1640->clock_pin = Pin(GPIO_TM1640CLK); + Tm1640->data_pin = Pin(GPIO_TM1640DIN); + + pinMode(Tm1640->data_pin, OUTPUT); + pinMode(Tm1640->clock_pin, OUTPUT); + digitalWrite(Tm1640->clock_pin, HIGH); + digitalWrite(Tm1640->data_pin, HIGH); + + Settings->display_model = XDSP_13; + +#ifdef USE_IOTTIMER + Settings->display_options.type = TM1640_IOTTIMER; + + Settings->display_cols[0] = 9; // 4 (left) + 2 (lower right) + 3 (upper right). + Settings->display_rows = 1; + Settings->display_width = Settings->display_cols[0]; + Settings->display_height = Settings->display_rows; + + Tm1640->clock_24 = true; + Tm1640->clock_seconds = true; + + IoTTimerDim(); + IoTTimerClearDisplay(); +#endif // USE_IOTTIMER + + AddLog(LOG_LEVEL_INFO, PSTR("DSP: TM1640 with %d digits (type %d)"), Settings->display_width, Settings->display_options.type); + } +} + + +/*********************************************************************************************\ +* IotTimer +\*********************************************************************************************/ + +#ifdef USE_IOTTIMER + +/* + (specifically for its use in the IOTTIMER WiFi clock) + + The WiFi LED clock called IOTTIMER has the following characteristics: + - Controlled by an ESP-12F + - Display with four 35 mm (1 12/32 in), two 21 mm (26/32 in), and three 12 mm (~1/2 in), + seven-segment LED digits, plus special symbols (alarm, AM/PM) + - TM1640B LED controller + - R8010 RTC with CR1220 battery + - Temperature sensor M1601 + - Ambient light sensor (analog voltage) + - Buzzer + - Three buttons on the backside + - USB C port for power supply (only) + + The TM1640B chip is a controller for a sixteen-digit seven-segment (plus dot) LED display. + It is also sometimes used to control a 16 x 8 LED matrix. The controller is controlled + through a proprietary two-wire serial interface bearing some similarities with I2C. The + two wires are called CLK and DIN. We use two GPIO pins and one-microsecond sleeps to + implement the required timing. + + The wiring of the LEDs in the IOTTIMER clock has been optimized for a simple routing of the + traces on the display board. The enumeration of the digit segments is non-standard, but + consistent across all digits. The bigger digits have two LEDs per segment, controlled by + separate digit lines of the LED controller. From the software perspective, they appear as + two layers of four digits each. + + The brightness of the LEDs can be controlled in seven steps (plus off). In theory, the + brightness of the segments with two LEDs could be set in fifteen levels (plus off). + To keep things simple and to avoid brightness gradients within segments, both LEDs of a + segment will always be set to the same level. + + The intention of this display driver (together with the drivers for the other components) + is to be able to use the IOTTIMER as an alarm clock that can be fully integrated in your + home automation using Tasmota and rules. + + This driver is not a generic TM1640B driver as use cases of the TM1640B in different + devices will differ significantly. +*/ + + + + + + +#define IOTTIMER_DIGITS 16 +#define IOTTIMER_DOT_BIT 2 + +static unsigned char IoTTimerDisplay[IOTTIMER_DIGITS]; + +// Wiring of the LEDs (per digit): +// +// Seg# Bit Hex +// 07 06 40 +// 08 01 07 00 80 01 +// 02 01 02 +// 06 04 05 03 20 08 +// 05 03 04 02 10 04 +// +// Font as per wiring: +static const byte IoTTimerFont[128] { +//0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 +// SP ! " # $ % & ' ( ) * + , - . / + 0x00, 0xA0, 0x81, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, // 0x20 +//0 1 2 3 4 5 6 7 8 9 : ; < = > ? + 0xF9, 0x09, 0x73, 0x5B, 0x8B, 0xDA, 0xFA, 0x49, 0xFB, 0xDB, 0x00, 0x00, 0x00, 0x12, 0x00, 0x63, // 0x30 +// @ A B C D E F G H I J K L M N O + 0x00, 0xEB, 0xBA, 0xF0, 0x3B, 0xF2, 0xE2, 0xFA, 0xAB, 0x09, 0x19, 0x00, 0xB0, 0x00, 0xE9, 0xF9, // 0x40 +// P Q R S T U V W X Y Z [ \ ] ^(°) _ + 0xE3, 0xAB, 0x22, 0xDA, 0xB2, 0xB9, 0x00, 0x00, 0x00, 0x4B, 0x00, 0xF0, 0x00, 0x59, 0xC3, 0x10, // 0x50 +// `=° a b c d e f g h i j k l m n o + 0x01, 0x7B, 0xBA, 0x32, 0x3B, 0xF3, 0xE2, 0xDB, 0xAA, 0x08, 0x19, 0x00, 0x09, 0x00, 0x2A, 0x3A, // 0x60 +// p q r s t u v w x y z { | } ~ DEL + 0xE3, 0xAB, 0x22, 0xDA, 0xB2, 0x38, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x0B, 0x09, 0xA2, 0x00, 0x00 // 0x70 +}; + + +void IoTTimerDim(void) +{ + TM1640SetBrightness (changeUIntScale(GetDisplayDimmer(), 0, 100, 0, 8)); +} + + +void IoTTimerDisplayOn (void) +{ + IoTTimerDim(); +} + + +void IoTTimerDisplayOff (void) +{ + TM1640SetBrightness (0); +} + + +void IoTTimerDisplayOnOff(void) +{ + if (disp_power) { + IoTTimerDisplayOn(); + } + else { + IoTTimerDisplayOff(); + } +} + + +void IoTTimerClearDisplay (void) +{ + for (int i = 0; i < IOTTIMER_DIGITS; i++) { + IoTTimerDisplay[i] = 0; + } + TM1640SendDataArray(0, IoTTimerDisplay, IOTTIMER_DIGITS); +} + + +/*********************************************************************************************\ +* Init function +\*********************************************************************************************/ +void IoTTimerInit(uint8_t mode) +{ + switch(mode) { + case DISPLAY_INIT_MODE: + IoTTimerDim(); + IoTTimerClearDisplay(); + break; + case DISPLAY_INIT_PARTIAL: + case DISPLAY_INIT_FULL: + IoTTimerDim(); + IoTTimerClearDisplay(); + break; + } +} + +void IoTTimerDrawStringAt(uint32_t x, uint32_t y, const char *str, uint32_t color = 0, uint32_t flag = 0); +void IoTTimerDrawStringAt(uint32_t x, uint32_t y, const char *str, uint32_t color, uint32_t flag) { + // displaytext [x] = 0123456789 + // Considers display as 1111223334 where 1111 is large white display, + // 22 is small white display, + // 333 is green display, + // 4 is "1" = pm, "2" = alarm, "3" = both + // Following also works - notice scattered dot(.), colon(:), minus(-) or plus(+) + // displaytext 12:34:56.7.8.9ab - Show all lights including "pm" (=a) and "alarm" (=b) + // displaytext 12:34:56 - Show time + // displaytext 05-11-24 - Show date + // displaytext [x6]12.3 - Show value in green leds + // displaytext [ztS] - Clear display and show current time with seconds + + bool alarm = false; + bool pm = false; + bool dot_left_up = false; + bool dot_left_dn = false; + bool dot_right_dn = false; + bool dot_right_up_left = false; + bool dot_right_up_right = false; + bool dash_left = false; + bool dash_right = false; + + char chr; + uint32_t idx = x; + const char *pos = str; + while (*pos) { + chr = *pos & 0x7F; // We only support 0 to 127 + switch (idx) { + case 0: + IoTTimerDisplay[12] = IoTTimerDisplay[13] = IoTTimerFont[chr]; // col 0 + break; + case 1: + IoTTimerDisplay[14] = IoTTimerDisplay[15] = IoTTimerFont[chr]; // col 1 + break; + case 2: + if (('.' == chr) || (':' == chr) || ('-' == chr) || ('+' == chr)) { + if ('.' == chr) { + dot_left_dn = true; + } + else if (':' == chr) { + dot_left_up = true; + dot_left_dn = true; + } + else if ('-' == chr) { + dash_left = true; + dash_right = true; + } + else if ('+' == chr) { + dot_left_up = true; + dot_left_dn = true; + dash_left = true; + dash_right = true; + } + idx--; + } else { + IoTTimerDisplay[4] = IoTTimerDisplay[5] = IoTTimerFont[chr]; // col 2 + } + break; + case 3: + IoTTimerDisplay[11] = IoTTimerDisplay[1] = IoTTimerFont[chr]; // col 3 + break; + case 4: + if (('.' == chr) || (':' == chr) || ('-' == chr)) { + idx--; // Skip + } else { + IoTTimerDisplay[6] = IoTTimerFont[chr]; // col 4 + } + break; + case 5: + IoTTimerDisplay[7] = IoTTimerFont[chr]; // col 5 + break; + case 6: + if ('.' == chr) { + dot_right_dn = true; + idx--; + } else { + // Upper right (green) + IoTTimerDisplay[9] = IoTTimerFont[chr]; // col 6 + } + break; + case 7: + if ('.' == chr) { + dot_right_up_left = true; + idx--; + } else { + IoTTimerDisplay[10] = IoTTimerFont[chr]; // col 7 + } + break; + case 8: + if ('.' == chr) { + dot_right_up_right = true; + idx--; + } else { + IoTTimerDisplay[8] = IoTTimerFont[chr]; // col 8 + } + break; + case 9: // col 9 + if (chr & 0x01) { // 1, A, a + pm = true; + } + if (chr & 0x02) { // 2, B, b + alarm = true; + } + break; + } + idx++; + pos++; + } + + // Dots and dash + if (alarm) { + IoTTimerDisplay[12] |= 1 << IOTTIMER_DOT_BIT; // Alarm symbol + } + if (pm) { + IoTTimerDisplay[13] |= 1 << IOTTIMER_DOT_BIT; // PM + } + if (dot_left_up) { + IoTTimerDisplay[14] |= 1 << IOTTIMER_DOT_BIT; // Upper dot + } + if (dot_left_dn) { + IoTTimerDisplay[4] |= 1 << IOTTIMER_DOT_BIT; // Lower dot + } + if (dot_right_dn) { + IoTTimerDisplay[7] |= 1 << IOTTIMER_DOT_BIT; // Blue dot + } + if (dot_right_up_left) { + IoTTimerDisplay[10] |= 1 << IOTTIMER_DOT_BIT; // Green dot left + } + if (dot_right_up_right) { + IoTTimerDisplay[8] |= 1 << IOTTIMER_DOT_BIT; // Green dot right + } + if (dash_left) { + IoTTimerDisplay[5] |= 1 << IOTTIMER_DOT_BIT; + } + if (dash_right) { + IoTTimerDisplay[15] |= 1 << IOTTIMER_DOT_BIT; + } + + TM1640SendDataArray(0, IoTTimerDisplay, IOTTIMER_DIGITS); +} + + +/*********************************************************************************************\ +* Displays floating point number in the upper right sub-display of the IOTTIMER. +* Format is always "[n]n[.]n" (negative number is "-n[.]n") +\*********************************************************************************************/ +void IoTTimerShowFloat(float f) { +/* + char buffer[16]; + ext_snprintf_P(buffer, sizeof(buffer),PSTR("%1_f"), &f); + IoTTimerDrawStringAt(6, 0, buffer); +*/ + bool negative = false; + float threshold = 99.95; + if (f < 0.0) { + f = -f; + negative = true; + threshold = 9.95; + } + uint8_t precision = 0; + if (f < threshold) { + f *= 10.0; + precision++; + } + uint32_t n = (uint32_t) (f + 0.5); + char buffer[5] = { 0 }; + if (negative) { + if (n > 99) { + n = 99; + } + buffer[0] = '-'; + } else { + if (n > 999) { + n = 999; + } + if (n / 100 != 0) { + buffer[0] = '0' + n / 100; + } + } + buffer[1] = '0' + n % 100 / 10; + uint32_t idx = 2; + if (precision == 1) { + buffer[2] = '.'; + idx++; + } + buffer[idx] = '0' + n % 10; + IoTTimerDrawStringAt(6, 0, buffer); +} + + +/*********************************************************************************************\ +* Update the temperature in the upper right corner. +\*********************************************************************************************/ +void IoTTimerUpdateTemperature(void) { + IoTTimerShowFloat(ConvertTempToFahrenheit(TasmotaGlobal.temperature_celsius)); +} + + +/*********************************************************************************************\ +* Adjust the brightness based on the photo diode voltage. +\*********************************************************************************************/ +void IoTTimerAdjustBrightness(void) { + // Max ADC value is 3400 [lx], but that is only reached in direct sun light. + // 20 is already quite bright. + // Illuminance value of 0 should map to level 1 (level 0 is off) + static float filteredLevel = 1.0; + float level = (float) AdcGetLux(0) / (20.0 / 7.0) + 1.0; + if (level > 8.0) level = 8.0; + if (level < 1.0) level = 1.0; + filteredLevel = 0.9 * filteredLevel + 0.1 * (float) level; + + TM1640SetBrightness ((int) (filteredLevel + 0.5)); +} + + +#ifdef USE_DISPLAY_MODES1TO5 + +/*********************************************************************************************\ +* Show the current time +\*********************************************************************************************/ +void IoTTimerShowTime(void) { + uint8_t hour = RtcTime.hour; + uint8_t min = RtcTime.minute; + uint8_t sec = RtcTime.second; + uint8_t symbol = 0; + + if (!Tm1640->clock_24) { + if (hour > 12) { + hour -= 12; + } + if (hour == 0) { + hour = 12; + } + symbol |= 1; + } + + char buffer[16]; + snprintf_P(buffer, sizeof(buffer), PSTR("%2d:%02d"), hour, min); + if (Tm1640->clock_seconds) { + snprintf_P(buffer, sizeof(buffer), PSTR("%s:%02d"), buffer, sec); + } + IoTTimerDrawStringAt(0, 0, buffer); + + if (Settings->timer[0].arm) { + symbol |= 2; + } + + snprintf_P(buffer, sizeof(buffer), PSTR("%d"), symbol); + IoTTimerDrawStringAt(9, 0, buffer); +} + + +/*********************************************************************************************\ +* Show the current date +\*********************************************************************************************/ +void IoTTimerShowDate(void) +{ + uint8_t left = RtcTime.day_of_month; + uint8_t middle = RtcTime.month; + uint8_t right = RtcTime.year % 100; + + if (!Tm1640->clock_24) { + // Use U.S. date format. + left = RtcTime.month; + middle = RtcTime.day_of_month; + } + + char buffer[16]; + snprintf_P(buffer, sizeof(buffer), PSTR("%02d-%02d-%02d"), left, middle, right); + IoTTimerDrawStringAt(0, 0, buffer); +} + + +void IoTTimerRefresh(void) { // Every second + // Update temperature display content: + IoTTimerUpdateTemperature(); + + // Auto-adjust brightness: + IoTTimerAdjustBrightness(); + + if (Settings->display_mode) { // Mode 0 is User text + switch (Settings->display_mode) { + case 1: // Time + IoTTimerShowTime(); + break; + case 2: // Date + IoTTimerShowDate(); + break; + case 3: // Time/Date + if (TasmotaGlobal.uptime % Settings->display_refresh) + { + IoTTimerShowTime(); + } + else + { + IoTTimerShowDate(); + } + break; + case 4: + case 5: + // not in use + break; + } + } +} + +#endif // USE_DISPLAY_MODES1TO5 + + +/*********************************************************************************************\ +* Displays a clock. +* Command: DisplayClock 1 // 12-hour format +* DisplayClock 2 // 24-hour format +* DisplayClock 3 // 12-hour without seconds +* DisplayClock 4 // 24-hour without seconds +\*********************************************************************************************/ +void CmndIoTTimerClock(void) { + uint16_t val = XdrvMailbox.payload; + + if (ArgC() == 0) + val = 0; + + if ((val < 1) || (val > 4)) + return; + + if (val == 1) { + Tm1640->show_clock = true; + Tm1640->clock_24 = false; + Tm1640->clock_seconds = true; + } + else if (val == 2) { + Tm1640->show_clock = true; + Tm1640->clock_24 = true; + Tm1640->clock_seconds = true; + } + else if (val == 3) { + Tm1640->show_clock = true; + Tm1640->clock_24 = false; + Tm1640->clock_seconds = false; + } + else if (val == 4) { + Tm1640->show_clock = true; + Tm1640->clock_24 = true; + Tm1640->clock_seconds = false; + } else { + Tm1640->show_clock = false; + Tm1640->clock_24 = false; + } + + IoTTimerClearDisplay(); +} + + +#endif // USE_IOTTIMER + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdsp13(uint32_t function) { + bool result = false; + + if (FUNC_DISPLAY_INIT_DRIVER == function) { + TM1640Init(); + } + else if (Tm1640 && (XDSP_13 == Settings->display_model)) { + +#ifdef USE_IOTTIMER + + switch (function) { + case FUNC_DISPLAY_INIT: + IoTTimerInit(dsp_init); + break; +#ifdef USE_DISPLAY_MODES1TO5 + case FUNC_DISPLAY_EVERY_SECOND: + IoTTimerRefresh(); + break; +#endif // USE_DISPLAY_MODES1TO5 + case FUNC_DISPLAY_MODEL: + result = true; + break; + case FUNC_DISPLAY_CLOCK: + CmndIoTTimerClock(); + break; + case FUNC_DISPLAY_CLEAR: + IoTTimerClearDisplay(); + break; + case FUNC_DISPLAY_NUMBER: + case FUNC_DISPLAY_NUMBERNC: + case FUNC_DISPLAY_FLOAT: + case FUNC_DISPLAY_FLOATNC: + IoTTimerShowFloat(CharToFloat(XdrvMailbox.data)); + break; + case FUNC_DISPLAY_DIM: + IoTTimerDim(); + break; + case FUNC_DISPLAY_POWER: + IoTTimerDisplayOnOff(); + break; + case FUNC_DISPLAY_DRAW_STRING: + IoTTimerDrawStringAt(dsp_x, dsp_y, dsp_str, dsp_color, dsp_flag); + break; + } + +#endif // USE_IOTTIMER + + } + return result; +} + +#endif // USE_DISPLAY_TM1640 +#endif // USE_DISPLAY From fe658424b890b9f7f5d60e76915f185e756b6421 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:49:15 +0100 Subject: [PATCH 147/205] Fix date/time rotation without seconds --- tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino b/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino index dd1d868d8..3f8032c22 100644 --- a/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino +++ b/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino @@ -605,6 +605,8 @@ void IoTTimerShowTime(void) { snprintf_P(buffer, sizeof(buffer), PSTR("%2d:%02d"), hour, min); if (Tm1640->clock_seconds) { snprintf_P(buffer, sizeof(buffer), PSTR("%s:%02d"), buffer, sec); + } else { + snprintf_P(buffer, sizeof(buffer), PSTR("%s "), buffer); // Erase seconds in case toggling between date/time } IoTTimerDrawStringAt(0, 0, buffer); From 6d0467489a833371309d369db55de2353d41417b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 Nov 2024 12:13:14 +0100 Subject: [PATCH 148/205] Add command `SetOption161 1` to disable display of state text (#22515) --- CHANGELOG.md | 1 + RELEASENOTES.md | 3 +- tasmota/include/tasmota_types.h | 2 +- .../xdrv_01_9_webserver.ino | 128 ++++++++++++------ 4 files changed, 89 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6a4c85bc..5563006e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ## [14.3.0.7] ### Added - Support for TM1640 based IoTTimer by Stefan Oskamp (#21376) +- Command `SetOption161 1` to disable display of state text (#22515) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f36832a88..c1707f58e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -116,7 +116,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ## Changelog v14.3.0.7 ### Added -- Add command ``WebColor20`` to control color of Button when Off +- Command `WebColor20` to control color of Button when Off +- Command `SetOption161 1` to disable display of state text (#22515) - DALI support for short addresses (gear) and groups - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index df347846c..dceb236ec 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -195,7 +195,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t mqtt_disable_modbus : 1; // bit 12 (v13.3.0.5) - SetOption158 - (MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead uint32_t counter_both_edges : 1; // bit 13 (v13.3.0.5) - SetOption159 - (Counter) Enable counting on both rising and falling edge (1) uint32_t ld2410_use_pin : 1; // bit 14 (v14.3.0.2) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1) - uint32_t spare15 : 1; // bit 15 + uint32_t gui_no_state_text : 1; // bit 15 (v14.3.0.7) - SetOption161 - (GUI) Disable display of state text (1) uint32_t spare16 : 1; // bit 16 uint32_t spare17 : 1; // bit 17 uint32_t spare18 : 1; // bit 18 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 3bc5634c5..86a88d6d4 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1238,6 +1238,53 @@ void HandleWifiLogin(void) { WSContentStop(); } +#ifdef USE_SHUTTER +/*-------------------------------------------------------------------------------------------*/ + +int32_t IsShutterWebButton(uint32_t idx) { + /* 0: Not a shutter, 1..4: shutter up idx, -1..-4: shutter down idx */ + int32_t ShutterWebButton = 0; + if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support + for (uint32_t i = 0; i < TasmotaGlobal.shutters_present ; i++) { + if (ShutterGetStartRelay(i) && ((ShutterGetStartRelay(i) == idx) || (ShutterGetStartRelay(i) == (idx-1)))) { + ShutterWebButton = (ShutterGetStartRelay(i) == idx) ? (i+1): (-1-i); + break; + } + } + } + return ShutterWebButton; +} +#endif // USE_SHUTTER + +/*-------------------------------------------------------------------------------------------*/ + +void WebGetDeviceCounts(uint32_t &buttons_non_light, uint32_t &buttons_non_light_non_shutter, uint32_t &shutter_button) { + buttons_non_light = TasmotaGlobal.devices_present; + +#ifdef USE_LIGHT + // Chk for reduced toggle buttons used by lights + if (TasmotaGlobal.light_type) { + // Find and skip light buttons (Lights are controlled by the last TasmotaGlobal.devices_present (or 2)) + buttons_non_light = LightDevice() -1; + } +#endif // USE_LIGHT + + buttons_non_light_non_shutter = buttons_non_light; + shutter_button = 0; // Bitmask for each button +#ifdef USE_SHUTTER + // Chk for reduced toggle buttons used by shutters + // Find and skip dedicated shutter buttons + if (buttons_non_light && Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support + for (uint32_t button_idx = 1; button_idx <= buttons_non_light; button_idx++) { + if (IsShutterWebButton(button_idx) != 0) { + buttons_non_light_non_shutter--; + shutter_button |= (1 << (button_idx -1)); // Set button bit in bitmask + } + } + } +#endif // USE_SHUTTER +} + #ifdef USE_LIGHT /*-------------------------------------------------------------------------------------------*/ @@ -1318,33 +1365,12 @@ void HandleRoot(void) { #ifndef FIRMWARE_MINIMAL if (TasmotaGlobal.devices_present) { - uint32_t buttons_non_light = TasmotaGlobal.devices_present; + uint32_t buttons_non_light; + uint32_t buttons_non_light_non_shutter; + uint32_t shutter_button; + WebGetDeviceCounts(buttons_non_light, buttons_non_light_non_shutter, shutter_button); uint32_t button_idx = 1; -#ifdef USE_LIGHT - // Chk for reduced toggle buttons used by lights - if (TasmotaGlobal.light_type) { - // Find and skip light buttons (Lights are controlled by the last TasmotaGlobal.devices_present (or 2)) - buttons_non_light = LightDevice() -1; - } -#endif // USE_LIGHT - - uint32_t buttons_non_light_non_shutter = buttons_non_light; - -#ifdef USE_SHUTTER - // Chk for reduced toggle buttons used by shutters - uint32_t shutter_button = 0; // Bitmask for each button - // Find and skip dedicated shutter buttons - if (buttons_non_light && Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support - for (button_idx = 1; button_idx <= buttons_non_light; button_idx++) { - if (IsShutterWebButton(button_idx) != 0) { - buttons_non_light_non_shutter--; - shutter_button |= (1 << (button_idx -1)); // Set button bit in bitmask - } - } - } -#endif // USE_SHUTTER - if (buttons_non_light_non_shutter) { // Any non light AND non shutter button // Display toggle buttons WSContentSend_P(HTTP_TABLE100); // "
" @@ -1428,6 +1454,10 @@ void HandleRoot(void) { } WSContentSend_P(PSTR("
")); + + if (1 == button_idx) { + button_idx = shutter_button_idx; + } } #endif // USE_SHUTTER @@ -1625,24 +1655,6 @@ void HandleRoot(void) { * HandleRootStatusRefresh \*-------------------------------------------------------------------------------------------*/ -#ifdef USE_SHUTTER -int32_t IsShutterWebButton(uint32_t idx) { - /* 0: Not a shutter, 1..4: shutter up idx, -1..-4: shutter down idx */ - int32_t ShutterWebButton = 0; - if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support - for (uint32_t i = 0; i < TasmotaGlobal.shutters_present ; i++) { - if (ShutterGetStartRelay(i) && ((ShutterGetStartRelay(i) == idx) || (ShutterGetStartRelay(i) == (idx-1)))) { - ShutterWebButton = (ShutterGetStartRelay(i) == idx) ? (i+1): (-1-i); - break; - } - } - } - return ShutterWebButton; -} -#endif // USE_SHUTTER - -/*-------------------------------------------------------------------------------------------*/ - bool WebUpdateSliderTime(void) { uint32_t slider_update_time = millis(); if (0 == Web.slider_update_time) { @@ -1879,6 +1891,36 @@ bool HandleRootStatusRefresh(void) { XsnsXdrvCall(FUNC_WEB_SENSOR); WSContentSend_P(PSTR("")); + if (!Settings->flag6.gui_no_state_text) { // SetOption161 - (GUI) Disable display of state text (1) + bool show_state = (TasmotaGlobal.devices_present); +#ifdef USE_SONOFF_IFAN + if (IsModuleIfan()) { show_state = false; } +#endif // USE_SONOFF_IFAN + if (show_state) { + uint32_t buttons_non_light; + uint32_t buttons_non_light_non_shutter; + uint32_t shutter_button; + WebGetDeviceCounts(buttons_non_light, buttons_non_light_non_shutter, shutter_button); + + if (buttons_non_light_non_shutter <= 8) { // Any non light AND non shutter button + WSContentSend_P(PSTR("{t}")); + uint32_t cols = buttons_non_light_non_shutter; + uint32_t fontsize = (cols < 5) ? 70 - (cols * 8) : 32; + for (uint32_t idx = 1; idx <= buttons_non_light; idx++) { + +#ifdef USE_SHUTTER + if (bitRead(shutter_button, idx -1)) { continue; } // Skip non-sequential shutter button +#endif // USE_SHUTTER + + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(TasmotaGlobal.power, idx -1)); + WSContentSend_P(HTTP_DEVICE_STATE, 100 / cols, (bitRead(TasmotaGlobal.power, idx -1)) ? PSTR("bold") : PSTR("normal"), fontsize, + (cols < 5) ? GetStateText(bitRead(TasmotaGlobal.power, idx -1)) : svalue); + } + WSContentSend_P(PSTR("")); + } + } + } + if (1 == Web.slider_update_time) { Web.slider_update_time = 0; } From 3c5cbade635139c81ee1d248db1c95e84bfec10c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:07:53 +0100 Subject: [PATCH 149/205] Restore iFan state text --- .../xdrv_01_9_webserver.ino | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 86a88d6d4..00fc1a7fe 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1891,12 +1891,20 @@ bool HandleRootStatusRefresh(void) { XsnsXdrvCall(FUNC_WEB_SENSOR); WSContentSend_P(PSTR("")); - if (!Settings->flag6.gui_no_state_text) { // SetOption161 - (GUI) Disable display of state text (1) - bool show_state = (TasmotaGlobal.devices_present); + if (!Settings->flag6.gui_no_state_text && // SetOption161 - (GUI) Disable display of state text (1) + TasmotaGlobal.devices_present) { + #ifdef USE_SONOFF_IFAN - if (IsModuleIfan()) { show_state = false; } + if (IsModuleIfan()) { + WSContentSend_P(PSTR("{t}")); + WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(TasmotaGlobal.power, 0)) ? PSTR("bold") : PSTR("normal"), 54, GetStateText(bitRead(TasmotaGlobal.power, 0))); + uint32_t fanspeed = GetFanspeed(); + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fanspeed); + WSContentSend_P(HTTP_DEVICE_STATE, 64, (fanspeed) ? PSTR("bold") : PSTR("normal"), 54, (fanspeed) ? svalue : GetStateText(0)); + WSContentSend_P(PSTR("")); + } else { #endif // USE_SONOFF_IFAN - if (show_state) { + uint32_t buttons_non_light; uint32_t buttons_non_light_non_shutter; uint32_t shutter_button; @@ -1918,7 +1926,11 @@ bool HandleRootStatusRefresh(void) { } WSContentSend_P(PSTR("")); } + +#ifdef USE_SONOFF_IFAN } +#endif // USE_SONOFF_IFAN + } if (1 == Web.slider_update_time) { From 1e9c5ad40e4c3ea044144b91988b1e98518a71a2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:30:27 +0100 Subject: [PATCH 150/205] Fix intermittent ESP32 serial lost on restart --- tasmota/tasmota_support/support_wifi.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index 35b07046e..aafabb631 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -216,7 +216,7 @@ void WifiBegin(uint8_t flag, uint8_t channel) { if (WiFi.getMode() != WIFI_AP_STA || !RgxApUp()) { // Preserve range extender connections (#17103) #endif // USE_WIFI_RANGE_EXTENDER WiFi.disconnect(true); // Delete SDK wifi config - delay(200); + delay(10); WifiSetMode(WIFI_STA); // Disable AP mode #ifdef USE_WIFI_RANGE_EXTENDER } From bf872defab175f1945c5e8859f858bc67118203a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:58:45 +0100 Subject: [PATCH 151/205] Fix use HTML escape on File System Edit File load (#22492) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5563006e8..9082e57f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. ### Fixed - ESP32 upgrade by file upload response based on file size (#22500) - Wrong GUI Module and Template drop down list indexes regression +- Use HTML escape on File System Edit File load (#22492) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index c1707f58e..98a599ce3 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -166,6 +166,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Fixed - FUNC_COMMAND linked list command buffer corruption by shutter driver +- Use HTML escape on File System Edit File load [#22492](https://github.com/arendst/Tasmota/issues/22492) - Prevent crashing when `display.ini` is missing end `#` [#22471](https://github.com/arendst/Tasmota/issues/22471) - Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) - Mitsubishi Electric HVAC Standby Stage for MiElHVAC [#22430](https://github.com/arendst/Tasmota/issues/22430) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino b/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino index 27c97ab85..84203d405 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino @@ -1603,7 +1603,7 @@ void UfsEditor(void) { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UFS: UfsEditor: read=%d"), l); if (l < 0) { break; } buf[l] = '\0'; - WSContentSend_P(PSTR("%s"), buf); + WSContentSend_P(PSTR("%s"), HtmlEscape((char*)buf).c_str()); filelen -= l; } fp.close(); From 16b6d353f4f5470b2693d1add1c73b1d76379a82 Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Fri, 22 Nov 2024 21:01:31 +0100 Subject: [PATCH 152/205] [Energy] Fix hardware sensor and restore (#22528) - Fix handling, when using hardware sensor for EnergytTotal (SO72) - Fix restore values, when device is off over midnight and power supply is unstable while powering on at the next day --- tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 8 ++++---- tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino index a26644832..5cb7fbb46 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino @@ -368,14 +368,14 @@ void EnergyUpdateTotal(void) { } } - if ((Energy->total[i] < (Energy->import_active[i] - 0.01f)) && // We subtract a little offset of 10Wh to avoid continuous updates - Settings->flag3.hardware_energy_total) { // SetOption72 - Enable hardware energy total counter as reference (#6561) + if (Settings->flag3.hardware_energy_total && // SetOption72 - Enable hardware energy total counter as reference (#6561) + fabs(Energy->total[i] - Energy->import_active[i]) > 0.01f) { // to avoid continuous updates, check for difference of min 10Wh // The following calculation allows total usage (Energy->import_active[i]) up to +/-2147483.647 kWh RtcSettings.energy_kWhtotal_ph[i] = (int32_t)((Energy->import_active[i] * 1000) - ((Energy->kWhtoday_offset[i] + Energy->kWhtoday[i]) / 100)); Settings->energy_kWhtotal_ph[i] = RtcSettings.energy_kWhtotal_ph[i]; Energy->total[i] = Energy->import_active[i]; Settings->energy_kWhtotal_time = (!Energy->kWhtoday_offset[i]) ? LocalTime() : Midnight(); - // AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total updated with hardware value")); + // AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: EnergyTotal updated with hardware value")); } } @@ -407,7 +407,7 @@ void Energy200ms(void) { } bool midnight = (LocalTime() == Midnight()); - if (midnight || (RtcTime.day_of_year > Settings->energy_kWhdoy)) { + if ((midnight || RtcTime.day_of_year > Settings->energy_kWhdoy) && TasmotaGlobal.uptime > 10) { Energy->kWhtoday_offset_init = true; Settings->energy_kWhdoy = RtcTime.day_of_year; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index 6b7423329..9fd4a0c47 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -624,14 +624,14 @@ void EnergyUpdateTotal(void) { } } - if ((Energy->total[i] < (Energy->import_active[i] - 0.01f)) && // We subtract a little offset of 10Wh to avoid continuous updates - Settings->flag3.hardware_energy_total) { // SetOption72 - Enable hardware energy total counter as reference (#6561) + if (Settings->flag3.hardware_energy_total && // SetOption72 - Enable hardware energy total counter as reference (#6561) + fabs(Energy->total[i] - Energy->import_active[i]) > 0.01f) { // to avoid continuous updates, check for difference of min 10Wh // The following calculation allows total usage (Energy->import_active[i]) up to +/-2147483.647 kWh RtcEnergySettings.energy_total_kWh[i] = Energy->import_active[i] - (Energy->energy_today_offset_kWh[i] + ((float)Energy->kWhtoday[i] / 100000)); Energy->Settings.energy_total_kWh[i] = RtcEnergySettings.energy_total_kWh[i]; Energy->total[i] = Energy->import_active[i]; Energy->Settings.energy_kWhtotal_time = (!Energy->energy_today_offset_kWh[i]) ? LocalTime() : Midnight(); - // AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total updated with hardware value")); + // AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: EnergyTotal updated with hardware value")); } } @@ -663,7 +663,7 @@ void Energy200ms(void) { } bool midnight = (LocalTime() == Midnight()); - if (midnight || (RtcTime.day_of_year > Energy->Settings.energy_kWhdoy)) { + if ((midnight || RtcTime.day_of_year > Energy->Settings.energy_kWhdoy) && TasmotaGlobal.uptime > 10) { Energy->kWhtoday_offset_init = true; Energy->Settings.energy_kWhdoy = RtcTime.day_of_year; From 4925e9c9a83b23e4bea9508851ae752f5212c41a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:17:26 +0100 Subject: [PATCH 153/205] Fix IoTTimer power off in DisplayModes 1 and up --- tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino b/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino index 3f8032c22..a4f0318e2 100644 --- a/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino +++ b/tasmota/tasmota_xdsp_display/xdsp_13_tm1640.ino @@ -641,6 +641,8 @@ void IoTTimerShowDate(void) void IoTTimerRefresh(void) { // Every second + if (!disp_power) { return; } + // Update temperature display content: IoTTimerUpdateTemperature(); From fb0666e6c88118f56041e747c9d817c19bddb194 Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Sat, 23 Nov 2024 09:46:25 +0200 Subject: [PATCH 154/205] Update `CHANGELOG.md` reference (#22534) Signed-off-by: Emmanuel Ferdman --- FIRMWARE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FIRMWARE.md b/FIRMWARE.md index ab98d6916..1c3ce9791 100644 --- a/FIRMWARE.md +++ b/FIRMWARE.md @@ -14,7 +14,7 @@ If you like **Tasmota**, give it a star, or fork it and contribute! [![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network) [![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota) -See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/CHANGELOG.md) for changes since last release. +See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/CHANGELOG.md) for changes since last release. ## Development From f255233f90d7def0987131b5914e02850bfdbb2f Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Sat, 23 Nov 2024 16:05:15 +0100 Subject: [PATCH 155/205] [Energy] Fix for New Year's Day (#22536) Fix rollover on New Year's Day --- tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino index 5cb7fbb46..baec24922 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino @@ -407,7 +407,7 @@ void Energy200ms(void) { } bool midnight = (LocalTime() == Midnight()); - if ((midnight || RtcTime.day_of_year > Settings->energy_kWhdoy) && TasmotaGlobal.uptime > 10) { + if ((midnight || RtcTime.day_of_year != Settings->energy_kWhdoy) && TasmotaGlobal.uptime > 10) { Energy->kWhtoday_offset_init = true; Settings->energy_kWhdoy = RtcTime.day_of_year; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index 9fd4a0c47..a30880199 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -663,7 +663,7 @@ void Energy200ms(void) { } bool midnight = (LocalTime() == Midnight()); - if ((midnight || RtcTime.day_of_year > Energy->Settings.energy_kWhdoy) && TasmotaGlobal.uptime > 10) { + if ((midnight || RtcTime.day_of_year != Energy->Settings.energy_kWhdoy) && TasmotaGlobal.uptime > 10) { Energy->kWhtoday_offset_init = true; Energy->Settings.energy_kWhdoy = RtcTime.day_of_year; From 3c703ac4d4e49de25d6154d2f4b8cc88494e9620 Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Sat, 23 Nov 2024 16:05:55 +0100 Subject: [PATCH 156/205] [Shutter] Fix UI inverted mode (#22538) Fix UI for shutter in inverted mode --- tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 00fc1a7fe..80616d21b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1424,6 +1424,7 @@ void HandleRoot(void) { int32_t ShutterWebButton; uint32_t shutter_button_idx = 1; + uint32_t shutter_button_idx_temp; for (uint32_t shutter_idx = 0; shutter_idx < TasmotaGlobal.shutters_present ; shutter_idx++) { while ((0 == shutter_button & (1 << (shutter_button_idx -1)))) { shutter_button_idx++; } @@ -1431,9 +1432,11 @@ void HandleRoot(void) { shutter_button_idx++; // Left button is next button first (down) for (uint32_t j = 0; j < 2; j++) { ShutterWebButton = IsShutterWebButton(shutter_button_idx); - WSContentSend_P(HTTP_DEVICE_CONTROL, 15, shutter_button_idx, shutter_button_idx, + shutter_button_idx_temp = ShutterGetOptions(abs(ShutterWebButton)-1) & 1 /* invert index */ ? shutter_button_idx + (j * 2) - 1 : shutter_button_idx; + // AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: j %d, ShutterWebButton %d, shutter_button_idx %d, shutter_idx %d, shutter_button_idx_temp %d"), j, ShutterWebButton, shutter_button_idx, shutter_idx, shutter_button_idx_temp); + WSContentSend_P(HTTP_DEVICE_CONTROL, 15, shutter_button_idx_temp, shutter_button_idx_temp, ((ShutterGetOptions(abs(ShutterWebButton)-1) & 2) /* is locked */ ? "-" : - ((ShutterGetOptions(abs(ShutterWebButton)-1) & 8) /* invert web buttons */ ? ((ShutterWebButton>0) ? "▼" : "▲") : ((ShutterWebButton>0) ? "▲" : "▼"))), + ((ShutterGetOptions(abs(ShutterWebButton)-1) & 1) /* invert web buttons */ ? (j ? "▼" : "▲") : (j ? "▲" : "▼"))), ""); if (1 == j) { break; } From b9414008df0e112d06fbc6be89a68b2c26566cb0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 23 Nov 2024 17:23:10 +0100 Subject: [PATCH 157/205] Hybrid compile: take custom boards settings in account (#22542) --- pio-tools/post_esp32.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py index 5fe75bf2b..e986a5021 100644 --- a/pio-tools/post_esp32.py +++ b/pio-tools/post_esp32.py @@ -45,19 +45,20 @@ sections = env.subst(env.get("FLASH_EXTRA_IMAGES")) chip = env.get("BOARD_MCU") mcu_build_variant = env.BoardConfig().get("build.variant", "").lower() flag_custom_sdkconfig = config.has_option("env:"+env["PIOENV"], "custom_sdkconfig") +flag_board_sdkconfig = env.BoardConfig().get("espidf.custom_sdkconfig", "") # Copy safeboots firmwares in place when running in Github github_actions = os.getenv('GITHUB_ACTIONS') extra_flags = ''.join([element.replace("-D", " ") for element in env.BoardConfig().get("build.extra_flags", "")]) build_flags = ''.join([element.replace("-D", " ") for element in env.GetProjectOption("build_flags")]) -if ("CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags) and flag_custom_sdkconfig == False: +if ("CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags) and flag_custom_sdkconfig == False and flag_board_sdkconfig == "": FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-solo1") if github_actions and os.path.exists("./firmware/firmware"): shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-solo1/variants/tasmota", dirs_exist_ok=True) if variants_dir: shutil.copytree("./firmware/firmware", variants_dir, dirs_exist_ok=True) -elif ("CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags) and flag_custom_sdkconfig == False: +elif ("CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags) and flag_custom_sdkconfig == False and flag_board_sdkconfig == "": FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-ITEAD") if github_actions and os.path.exists("./firmware/firmware"): shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-ITEAD/variants/tasmota", dirs_exist_ok=True) From 25f13e434f2070b14a4fec76863a37d9268623a0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 24 Nov 2024 16:07:36 +0100 Subject: [PATCH 158/205] TasmotaClient discard GET_JSON timeout --- tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino b/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino index 345fc9dba..ef0a5b4d3 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino @@ -444,8 +444,10 @@ void TasmotaClient_Show(void) { char buffer[250]; // Keep size below 255 to stay within 8-bits index and len uint8_t len = TasmotaClient_receiveData(buffer, sizeof(buffer) -1); - buffer[len] = '\0'; - ResponseAppend_P(PSTR(",\"TasmotaClient\":%s"), buffer); + if (len) { + buffer[len] = '\0'; + ResponseAppend_P(PSTR(",\"TasmotaClient\":%s"), buffer); + } } } From 3448e173178dee294b66200d15b7a18a565c4e73 Mon Sep 17 00:00:00 2001 From: Felix Laevsky Date: Sun, 24 Nov 2024 19:44:18 +0200 Subject: [PATCH 159/205] Added 2 new filters: BLE filter by name and minimum RSSI (#22530) --- .../tasmota_xdrv_driver/xdrv_79_esp32_ble.ino | 107 +++++++++++++++++- 1 file changed, 103 insertions(+), 4 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino index 2c5aa816d..a8bdf572b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino @@ -108,6 +108,9 @@ BLEEnableUnsaved *0/1 - if BLE is disabled, this can be used to enable BLE without it being saved - useful as the last command in autoexec.bat + BLEFilterNames + BLEFilterNames0 - clear filter list + BLEFilterNames1 - , - set one or more device names Other drivers can add callbacks to receive advertisements Other drivers can add 'operations' to be performed and receive callbacks from the operation's success or failure @@ -134,6 +137,8 @@ i.e. the Bluetooth of the ESP can be shared without conflict. */ #define BLE_ESP32_ALIASES +#define BLE_ESP32_FILTER_BY_NAME +#define BLE_ESP32_FILTER_BY_RSSI // uncomment for more diagnostic/information messages - + more flash use. //#define BLE_ESP32_DEBUG @@ -472,6 +477,12 @@ std::deque scancompleteCallbacks; std::deque aliases; #endif +#ifdef BLE_ESP32_FILTER_BY_NAME +std::vector bleFilterNames; +#endif +#ifdef BLE_ESP32_FILTER_BY_RSSI +int minRSSI = -100; +#endif /*********************************************************************************************\ * constants @@ -480,7 +491,7 @@ std::deque aliases; #define D_CMND_BLE "BLE" const char kBLE_Commands[] PROGMEM = D_CMND_BLE "|" - "Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved"; + "Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved|FilterNames|MinRssiLevel"; static void CmndBLEPeriod(void); static void CmndBLEAdv(void); @@ -495,6 +506,8 @@ static void CmndBLEDevices(void); static void CmndBLEMaxAge(void); static void CmndBLEAddrFilter(void); static void CmndBLEEnableUnsaved(void); +static void CmndBleFilterNames(void); +static void CmndSetMinRSSI(void); void (*const BLE_Commands[])(void) PROGMEM = { &BLE_ESP32::CmndBLEPeriod, @@ -509,7 +522,9 @@ void (*const BLE_Commands[])(void) PROGMEM = { &BLE_ESP32::CmndBLEDevices, &BLE_ESP32::CmndBLEMaxAge, &BLE_ESP32::CmndBLEAddrFilter, - &BLE_ESP32::CmndBLEEnableUnsaved + &BLE_ESP32::CmndBLEEnableUnsaved, + &BLE_ESP32::CmndBleFilterNames, + &BLE_ESP32::CmndSetMinRSSI }; const char *successStates[] PROGMEM = { @@ -1128,7 +1143,24 @@ void ReverseMAC(uint8_t _mac[]){ } - +/** + * @brief Search for device name in filer list + * + * @param deviceName device name string + */ +#ifdef BLE_ESP32_FILTER_BY_NAME +bool isDeviceInFilter(const String& deviceName) { +#ifdef BLE_ESP32_DEBUG + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: Device chcked in filter %s"), deviceName); +#endif + for (const auto& filterName : bleFilterNames) { + if (deviceName == filterName) { + return true; + } + } + return false; +} +#endif /*********************************************************************************************\ * Advertisment details @@ -1372,9 +1404,24 @@ class BLEAdvCallbacks: public NimBLEScanCallbacks { BLEAdvertisment.name[sizeof(BLEAdvertisment.name)-1] = 0; } + int filter = 0; +#ifdef BLE_ESP32_FILTER_BY_NAME + if (!bleFilterNames.empty()) { + if (!advertisedDevice->haveName() || !isDeviceInFilter(namestr)) + { + filter = 1; + } + } +#endif + +#ifdef BLE_ESP32_FILTER_BY_RSSI + if (advertisedDevice->getRSSI() < minRSSI) { + filter = 1; + } +#endif // log this device safely - if (BLEAdvertisment.addrtype <= BLEAddressFilter){ + if ((BLEAdvertisment.addrtype <= BLEAddressFilter) && (0 == filter) ){ addSeenDevice(BLEAdvertisment.addr, BLEAdvertisment.addrtype, BLEAdvertisment.name, BLEAdvertisment.RSSI); } @@ -2833,6 +2880,58 @@ void CmndBLEDetails(void){ } +void CmndBleFilterNames(void) { +#ifdef BLE_ESP32_FILTER_BY_NAME + int op = XdrvMailbox.index; +#ifdef BLE_ESP32_DEBUG + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: Name %d %s"), op, XdrvMailbox.data); +#endif + + switch(op){ + case 0:{ + bleFilterNames.clear(); + ResponseCmndDone(); + } break; + case 1:{ + if (XdrvMailbox.data_len) { + String filters = XdrvMailbox.data; + bleFilterNames.clear(); + + int start = 0; + int end = filters.indexOf(','); + while (end != -1) { + bleFilterNames.push_back(filters.substring(start, end)); + start = end + 1; + end = filters.indexOf(',', start); + } + bleFilterNames.push_back(filters.substring(start)); + + Response_P(PSTR("{\"BLEFilterNames\":\"%s\"}"), filters.c_str()); + } else { + String filterList; + for (const auto& name : bleFilterNames) { + if (!filterList.isEmpty()) { + filterList += ", "; + } + filterList += name; + } + + Response_P(PSTR("{\"BLEFilterNames\":\"%s\"}"), filterList.c_str()); + } + } break; + } +#endif +} + +void CmndSetMinRSSI(void) { +#ifdef BLE_ESP32_FILTER_BY_RSSI + if (XdrvMailbox.data_len) { + minRSSI = atoi(XdrvMailbox.data); + } + Response_P(PSTR("{\"MinRSSI\":\"%d\"}"), minRSSI); +#endif +} + void CmndBLEAlias(void){ #ifdef BLE_ESP32_ALIASES int op = XdrvMailbox.index; From 2402f7cbd103391e61b6e0a0d5ebd8bc90902042 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Sun, 24 Nov 2024 23:30:24 +0100 Subject: [PATCH 160/205] Berry simplify DAC support (#22546) --- .../tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino index 4c1f0f711..97eb571e4 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino @@ -23,13 +23,6 @@ #include #include "esp8266toEsp32.h" -#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) -#if ESP_IDF_VERSION_MAJOR >= 5 -#include -#else -#include -#endif -#endif /*********************************************************************************************\ * Native functions mapped to Berry functions * @@ -40,9 +33,10 @@ extern "C" { #include "berry/include/be_gpio_defines.h" -#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) +#ifdef SOC_DAC_SUPPORTED #include "soc/dac_channel.h" -#endif // defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) + #include +#endif // SOC_DAC_SUPPORTED // virtual member int gp_member(bvm *vm); @@ -65,7 +59,7 @@ extern "C" { // synthetic mode if (-1 == mode) { // DAC -#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) +#ifdef SOC_DAC_SUPPORTED if (pin != DAC_CHAN0_GPIO_NUM && pin != DAC_CHAN1_GPIO_NUM) { be_raisef(vm, "value_error", "DAC only supported on GPIO%i-%i", DAC_CHAN0_GPIO_NUM, DAC_CHAN1_GPIO_NUM); } @@ -113,7 +107,7 @@ extern "C" { int gp_dac_voltage(bvm *vm); int gp_dac_voltage(bvm *vm) { -#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) +#ifdef SOC_DAC_SUPPORTED int32_t argc = be_top(vm); // Get the number of arguments if (argc == 2 && be_isint(vm, 1) && be_isnumber(vm, 2)) { int32_t pin = be_toint(vm, 1); From e397c11e70d343040ce8d0f6c5511e53f76ce91d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:33:34 +0100 Subject: [PATCH 161/205] Revert wifi delay --- tasmota/tasmota_support/support_wifi.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index aafabb631..35b07046e 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -216,7 +216,7 @@ void WifiBegin(uint8_t flag, uint8_t channel) { if (WiFi.getMode() != WIFI_AP_STA || !RgxApUp()) { // Preserve range extender connections (#17103) #endif // USE_WIFI_RANGE_EXTENDER WiFi.disconnect(true); // Delete SDK wifi config - delay(10); + delay(200); WifiSetMode(WIFI_STA); // Disable AP mode #ifdef USE_WIFI_RANGE_EXTENDER } From 3ab87273e6a1143cbfbbc14e0529ba79218eb07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20Zi=C3=B3=C5=82kowski?= Date: Mon, 25 Nov 2024 10:38:43 +0100 Subject: [PATCH 162/205] Shitf595 dynamic device count (#22543) * Make max Shift595 device count dynamic * Update xdrv_60_shift595.ino --- tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino index 809ec86ac..53c9a2110 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino @@ -88,7 +88,7 @@ void Shift595SwitchRelay(void) { } void CmndShift595Devices(void) { - if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 3)) { + if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload * 8 <= MAX_RELAYS_SET - Shift595->first)) { Settings->shift595_device_count = (1 == XdrvMailbox.payload) ? SHIFT595_DEVICE_COUNT : XdrvMailbox.payload; TasmotaGlobal.restart_flag = 2; } From 155dea98cddaf494ccaefb3bb4200af94cac2c27 Mon Sep 17 00:00:00 2001 From: Barbudor Date: Mon, 25 Nov 2024 10:56:35 +0100 Subject: [PATCH 163/205] Issue#22535 applying masking window to any power change (#22539) * apply masking to any power change * stupid typo * rephrase --- tasmota/tasmota_xdrv_driver/xdrv_71_magic_switch.ino | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_71_magic_switch.ino b/tasmota/tasmota_xdrv_driver/xdrv_71_magic_switch.ino index a0c097b28..46bc1e062 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_71_magic_switch.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_71_magic_switch.ino @@ -105,6 +105,12 @@ void MagicSwitchLoop() } } +void MagicSwitchSetPower(void) { + // It can happen that on relay switch, disturbances on the mains is falsy see as a MagicSwitch pulse + // This restart the masking windows on every power change to avoid that effect + MagicSwitch->switch_state = MAGICSWITCH_MASKING_WINDOW_LEN; +} + /******************************************************************************************************** * Driver initialisation */ @@ -173,6 +179,9 @@ bool Xdrv71(uint32_t function) { //case FUNC_EVERY_250_MSECOND: MagicSwitchLoop(); break; + case FUNC_SET_POWER: + MagicSwitchSetPower(); + break; case FUNC_ADD_SWITCH: result = MagicSwitchAddSwitch(); break; From 2322646773f39ff0e12da8fb412b2b92b3839849 Mon Sep 17 00:00:00 2001 From: Andy Knight Date: Tue, 26 Nov 2024 10:28:55 +0000 Subject: [PATCH 164/205] Prevent active BLE operations with unencrypted MI-format beacons (#22453) --- tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino index 3818717f8..752e2fdd1 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino @@ -792,7 +792,7 @@ int genericSensorReadFn(int slot, int force){ break;*/ case MI_LYWSD03MMC: // don't read if key present and we've decoded at least one advert - if (MIBLEsensors[slot].needkey == KEY_REQUIRED_AND_FOUND && !force) return -2; + if ((MIBLEsensors[slot].needkey == KEY_NOT_REQUIRED || MIBLEsensors[slot].needkey == KEY_REQUIRED_AND_FOUND) && !force) return -2; res = MI32Operation(slot, OP_READ_HT_LY, LYWSD03_Svc, nullptr, LYWSD03_BattNotifyChar); break; case MI_LYWSD02MMC: @@ -800,7 +800,7 @@ int genericSensorReadFn(int slot, int force){ break; case MI_MHOC401: // don't read if key present and we've decoded at least one advert - if (MIBLEsensors[slot].needkey == KEY_REQUIRED_AND_FOUND && !force) return -2; + if ((MIBLEsensors[slot].needkey == KEY_NOT_REQUIRED || MIBLEsensors[slot].needkey == KEY_REQUIRED_AND_FOUND) && !force) return -2; res = MI32Operation(slot, OP_READ_HT_LY, MHOC401_Svc, nullptr, MHOC401_BattNotifyChar); break; From 5dd132bb5f3865afa28d13bf27c0a6c228b0a9e7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:05:01 +0100 Subject: [PATCH 165/205] Update changelogs --- CHANGELOG.md | 4 ++++ RELEASENOTES.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9082e57f0..0f95ca205 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ All notable changes to this project will be documented in this file. ### Added - Support for TM1640 based IoTTimer by Stefan Oskamp (#21376) - Command `SetOption161 1` to disable display of state text (#22515) +- ESP32 new BLE filters by name and minimum RSSI (#22530) +- ESP32 Hybrid compile take custom boards settings in account (#22542) ### Breaking Changed @@ -14,11 +16,13 @@ All notable changes to this project will be documented in this file. - ESP32 max number of supported switches/buttons/relays from 28 to 32 - ESP32 max number of interlocks from 14 to 16 - ESP32 Platform from 2024.11.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.241030 to v3.1.0.241117 and IDF to 5.3.1.241024 (#22504) +- Prevent active BLE operations with unencrypted MI-format beacons (#22453) ### Fixed - ESP32 upgrade by file upload response based on file size (#22500) - Wrong GUI Module and Template drop down list indexes regression - Use HTML escape on File System Edit File load (#22492) +- Magic switch applying masking window to any power change (#22535) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 98a599ce3..c3457d732 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -138,6 +138,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC [#22370](https://github.com/arendst/Tasmota/issues/22370) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) +- ESP32 new BLE filters by name and minimum RSSI [#22530](https://github.com/arendst/Tasmota/issues/22530) +- ESP32 Hybrid compile take custom boards settings in account [#22542](https://github.com/arendst/Tasmota/issues/22542) - ESP32 MI32 legacy add config operations [#22458](https://github.com/arendst/Tasmota/issues/22458) - BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300) - Berry add I2C read16/write16 supporting Little Endian [#22448](https://github.com/arendst/Tasmota/issues/22448) @@ -160,6 +162,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI renamed commands `DaliCommission` to `DaliScan` and `DaliWeb` to `DaliLight` - DALI set Tasmota light control as default - Shutter optimized behavior to publish shutter data with sensor request [#22353](https://github.com/arendst/Tasmota/issues/22353) +- Prevent active BLE operations with unencrypted MI-format beacons [#22453](https://github.com/arendst/Tasmota/issues/22453) - ESP32 max number of supported switches/buttons/relays from 28 to 32 - ESP32 max number of interlocks from 14 to 16 - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) @@ -168,6 +171,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - FUNC_COMMAND linked list command buffer corruption by shutter driver - Use HTML escape on File System Edit File load [#22492](https://github.com/arendst/Tasmota/issues/22492) - Prevent crashing when `display.ini` is missing end `#` [#22471](https://github.com/arendst/Tasmota/issues/22471) +- Magic switch applying masking window to any power change [#22535](https://github.com/arendst/Tasmota/issues/22535) - Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) - Mitsubishi Electric HVAC Standby Stage for MiElHVAC [#22430](https://github.com/arendst/Tasmota/issues/22430) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) From 5a32df5e815da485457960b1fd470728bb40ffd5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:48:30 +0100 Subject: [PATCH 166/205] Fix Shift595 output offsets and restart relay toggles --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/tasmota_support/support.ino | 18 ++++- tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 7 ++ .../xdrv_28_pcf8574_v2.ino | 1 + .../tasmota_xdrv_driver/xdrv_60_shift595.ino | 79 +++++++++++++------ .../tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino | 1 + 7 files changed, 84 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f95ca205..e66fc9fa0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file. - Wrong GUI Module and Template drop down list indexes regression - Use HTML escape on File System Edit File load (#22492) - Magic switch applying masking window to any power change (#22535) +- Shift595 output offsets and restart relay toggles ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index c3457d732..ca9c3883b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -169,6 +169,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Fixed - FUNC_COMMAND linked list command buffer corruption by shutter driver +- Shift595 output offsets and restart relay toggles - Use HTML escape on File System Edit File load [#22492](https://github.com/arendst/Tasmota/issues/22492) - Prevent crashing when `display.ini` is missing end `#` [#22471](https://github.com/arendst/Tasmota/issues/22471) - Magic switch applying masking window to any power change [#22535](https://github.com/arendst/Tasmota/issues/22535) diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index 4c96ad7aa..76f5ac099 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -832,12 +832,28 @@ int32_t UpdateDevicesPresent(int32_t change) { else if (devices_present >= POWER_SIZE) { // Support up to uint32_t as bitmask difference = devices_present - POWER_SIZE; devices_present = POWER_SIZE; - AddLog(LOG_LEVEL_DEBUG, PSTR("APP: Max number of devices reached")); +// AddLog(LOG_LEVEL_DEBUG, PSTR("APP: Max 32 devices supported")); } TasmotaGlobal.devices_present = devices_present; return difference; } +void DevicesPresentNonDisplayOrLight(uint32_t &devices_claimed) { + uint32_t display_and_lights = 0; +#ifdef USE_LIGHT + display_and_lights += LightDevices(); // Skip light(s) +#endif // USE_LIGHT +#ifdef USE_DISPLAY + if (disp_device) { + display_and_lights++; // Skip display + } +#endif // USE_DISPLAY + uint32_t devices_present = TasmotaGlobal.devices_present - display_and_lights; + if (devices_claimed > devices_present) { + devices_claimed = devices_present; // Reduce amount of claimed devices + } +} + char* GetPowerDevice(char* dest, uint32_t idx, size_t size, uint32_t option) { strncpy_P(dest, S_RSLT_POWER, size); // POWER diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino index 047da5b43..cb8e081b4 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino @@ -293,6 +293,13 @@ uint8_t LightDevice(void) return Light.device; // Make external } +uint32_t LightDevices(void) { + if (0 == Light.device) { + return 0; + } + return TasmotaGlobal.devices_present - Light.device +1; // Make external +} + static uint32_t min3(uint32_t a, uint32_t b, uint32_t c) { return (a < b && a < c) ? a : (b < c) ? b : c; } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino index 874cbd772..b0f4420ce 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574_v2.ino @@ -374,6 +374,7 @@ void Pcf8574Power(void) { rpower >>= Pcf8574.relay_offset; relay_max = Pcf8574.relay_max; } + DevicesPresentNonDisplayOrLight(relay_max); // Skip display and/or light(s) for (uint32_t index = 0; index < relay_max; index++) { power_t state = rpower &1; if (Pcf8574PinUsed(GPIO_REL1, index)) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino index 53c9a2110..c1c1280d6 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino @@ -31,15 +31,28 @@ struct Shift595 { uint8_t pinOE; uint8_t outputs; uint8_t first; - bool connected = false; } *Shift595 = nullptr; +/*********************************************************************************************\ + * Low level Shift 74x595 +\*********************************************************************************************/ + void Shift595ConfigurePin(uint8_t pin, uint8_t value = 0) { pinMode(pin, OUTPUT); digitalWrite(pin, value); } -void Shift595Init(void) { +void Shift595LatchPin(uint8_t pin) { + digitalWrite(pin, 1); + digitalWrite(pin, 0); +} + +/*********************************************************************************************\ + * FUNC_SETUP_RING2 at T +1 + * Claim devices_present +\*********************************************************************************************/ + +void Shift595ModuleInit(void) { if (PinUsed(GPIO_SHIFT595_SRCLK) && PinUsed(GPIO_SHIFT595_RCLK) && PinUsed(GPIO_SHIFT595_SER)) { Shift595 = (struct Shift595*)calloc(1, sizeof(struct Shift595)); if (Shift595) { @@ -53,40 +66,60 @@ void Shift595Init(void) { if (PinUsed(GPIO_SHIFT595_OE)) { Shift595->pinOE = Pin(GPIO_SHIFT595_OE); - Shift595ConfigurePin(Shift595->pinOE, 1); + if (ResetReasonPowerOn()) { // Fix relay toggle at restart + Shift595ConfigurePin(Shift595->pinOE, 1); // Set all outputs to 3-state (3-state converted to OFF by ULN2803 relay drivers) + } } - Shift595->first = TasmotaGlobal.devices_present; - Shift595->outputs = Settings->shift595_device_count * 8; + Shift595->first = TasmotaGlobal.devices_present; // devices_present offset + Shift595->outputs = Settings->shift595_device_count * 8; // Max number of outputs present UpdateDevicesPresent(Shift595->outputs); - - Shift595->connected = true; - AddLog(LOG_LEVEL_DEBUG, PSTR("595: Controlling relays POWER%d to POWER%d"), Shift595->first + 1, Shift595->first + Shift595->outputs); } } } -void Shift595LatchPin(uint8_t pin) { - digitalWrite(pin, 1); - digitalWrite(pin, 0); -} +/*********************************************************************************************\ + * FUNC_SET_POWER at T +2 + * Reduce devices_present with display and/or lights not known before + * Add offset for previous defined relays +\*********************************************************************************************/ void Shift595SwitchRelay(void) { - if (Shift595 && Shift595->connected == true) { - for (uint32_t i = 0; i < Shift595->outputs; i++) { - uint8_t relay_state = bitRead(XdrvMailbox.index, Shift595->first + Shift595->outputs -1 -i); - digitalWrite(Shift595->pinSER, Settings->flag5.shift595_invert_outputs ? !relay_state : relay_state); - Shift595LatchPin(Shift595->pinSRCLK); - } + // XdrvMailbox.index = 32-bit rpower bit mask + // Use relative and sequential relay indexes + power_t rpower = XdrvMailbox.index; + uint32_t relay_max = Shift595->outputs; // Total number of outputs + DevicesPresentNonDisplayOrLight(relay_max); // Skip display and/or light(s) + uint32_t relay_offset = Shift595->outputs - relay_max + Shift595->first; - Shift595LatchPin(Shift595->pinRCLK); + static bool first = false; + if (!first) { + AddLog(LOG_LEVEL_DEBUG, PSTR("595: Output 1 to %d use POWER%d to POWER%d"), Shift595->outputs - relay_offset, Shift595->first + 1, relay_max); + first = true; + } - if (PinUsed(GPIO_SHIFT595_OE)) { - digitalWrite(Shift595->pinOE, 0); + uint32_t power_bit = relay_max -1; // Start at highest non display and/or light power bit + for (uint32_t i = 0; i < Shift595->outputs; i++) { // We need to set all shift outputs even if not used + uint32_t relay_state = 0; // Unused state + if (i >= relay_offset) { + relay_state = bitRead(rpower, power_bit); // Shift-in from high to low + power_bit--; } + digitalWrite(Shift595->pinSER, Settings->flag5.shift595_invert_outputs ? !relay_state : relay_state); // SetOption133 - (Shift595) Invert outputs of 74x595 shift registers + Shift595LatchPin(Shift595->pinSRCLK); + } + + Shift595LatchPin(Shift595->pinRCLK); + + if (PinUsed(GPIO_SHIFT595_OE)) { + digitalWrite(Shift595->pinOE, 0); } } +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + void CmndShift595Devices(void) { if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload * 8 <= MAX_RELAYS_SET - Shift595->first)) { Settings->shift595_device_count = (1 == XdrvMailbox.payload) ? SHIFT595_DEVICE_COUNT : XdrvMailbox.payload; @@ -102,8 +135,8 @@ void CmndShift595Devices(void) { bool Xdrv60(uint32_t function) { bool result = false; - if (FUNC_PRE_INIT == function) { - Shift595Init(); + if (FUNC_SETUP_RING2 == function) { + Shift595ModuleInit(); } else if (Shift595) { switch (function) { case FUNC_SET_POWER: diff --git a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino index 8cb1196ac..426293236 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino @@ -762,6 +762,7 @@ void MCP23xPower(void) { rpower >>= Mcp23x.relay_offset; relay_max = Mcp23x.relay_max; } + DevicesPresentNonDisplayOrLight(relay_max); // Skip display and/or light(s) for (uint32_t index = 0; index < relay_max; index++) { power_t state = rpower &1; if (MCP23xPinUsed(GPIO_REL1, index)) { From e8d5e442bf375d3313271d09932d4655b12c7b19 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:01:23 +0100 Subject: [PATCH 167/205] Update xdrv_60_shift595.ino --- tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino index c1c1280d6..513723c7f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino @@ -66,9 +66,9 @@ void Shift595ModuleInit(void) { if (PinUsed(GPIO_SHIFT595_OE)) { Shift595->pinOE = Pin(GPIO_SHIFT595_OE); - if (ResetReasonPowerOn()) { // Fix relay toggle at restart - Shift595ConfigurePin(Shift595->pinOE, 1); // Set all outputs to 3-state (3-state converted to OFF by ULN2803 relay drivers) - } + // Fix relay toggle at restart + // On power ON set all outputs to 3-state (3-state converted to OFF by ULN2803 relay drivers) + Shift595ConfigurePin(Shift595->pinOE, ResetReasonPowerOn()); } Shift595->first = TasmotaGlobal.devices_present; // devices_present offset From 8cb9345a97ae8a579e1490ef049e36ce566fda98 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:05:43 +0100 Subject: [PATCH 168/205] Fix compilation --- tasmota/tasmota_support/support.ino | 4 +--- tasmota/tasmota_xdrv_driver/xdrv_13_display.ino | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index 76f5ac099..b9619a90c 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -844,9 +844,7 @@ void DevicesPresentNonDisplayOrLight(uint32_t &devices_claimed) { display_and_lights += LightDevices(); // Skip light(s) #endif // USE_LIGHT #ifdef USE_DISPLAY - if (disp_device) { - display_and_lights++; // Skip display - } + display_and_lights += DisplayDevices(); // Skip display #endif // USE_DISPLAY uint32_t devices_present = TasmotaGlobal.devices_present - display_and_lights; if (devices_claimed > devices_present) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino index 33a445527..8096c4eaf 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino @@ -269,6 +269,12 @@ bool disp_subscribed = false; /*********************************************************************************************/ +uint32_t DisplayDevices(void) { + return (disp_device); +} + +/*********************************************************************************************/ + void DisplayClear(void) { if (renderer) { renderer->fillScreen(bg_color); From db0287e566d812f79a96324791285ab594528c4b Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Wed, 27 Nov 2024 22:11:57 +0100 Subject: [PATCH 169/205] Replace NeoPixelBus with TasmotaLED on ESP32x (#22556) * Replace NeoPixelBus with TasmotaLED on ESP32x * update changelog --- CHANGELOG.md | 2 + .../src/internal/NeoEsp32RmtMethod_idf5.h | 2 +- lib/lib_basic/TasmotaLED/library.json | 17 + lib/lib_basic/TasmotaLED/src/TasmotaLED.cpp | 237 ++ lib/lib_basic/TasmotaLED/src/TasmotaLED.h | 129 + .../TasmotaLED/src/TasmotaLEDPusher.cpp | 97 + .../TasmotaLED/src/TasmotaLEDPusher.h | 161 ++ .../TasmotaLED/src/TasmotaLEDPusherRMT.cpp | 240 ++ .../TasmotaLED/src/TasmotaLEDPusherSPI.cpp | 191 ++ lib/libesp32/berry/default/be_modtab.c | 4 +- .../berry_animate/src/be_berry_leds_frame.cpp | 20 +- .../berry_tasmota/src/be_leds_ntv_lib.c | 15 +- .../berry_tasmota/src/embedded/leds.be | 65 +- .../src/solidify/solidified_leds.h | 2147 ++++++++--------- tasmota/my_user_config.h | 21 +- .../xdrv_04_light_artnet.ino | 2 +- .../xdrv_52_3_berry_leds.ino | 162 +- tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino | 11 +- .../xlgt_01_ws2812_esp32.ino | 899 +++++++ 19 files changed, 3126 insertions(+), 1296 deletions(-) create mode 100644 lib/lib_basic/TasmotaLED/library.json create mode 100644 lib/lib_basic/TasmotaLED/src/TasmotaLED.cpp create mode 100644 lib/lib_basic/TasmotaLED/src/TasmotaLED.h create mode 100644 lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.cpp create mode 100644 lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.h create mode 100644 lib/lib_basic/TasmotaLED/src/TasmotaLEDPusherRMT.cpp create mode 100644 lib/lib_basic/TasmotaLED/src/TasmotaLEDPusherSPI.cpp create mode 100644 tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index e66fc9fa0..35534baa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,14 @@ All notable changes to this project will be documented in this file. - ESP32 Hybrid compile take custom boards settings in account (#22542) ### Breaking Changed +- ArtNet on ESP32 switches from GRB to RGB encoding ### Changed - ESP32 max number of supported switches/buttons/relays from 28 to 32 - ESP32 max number of interlocks from 14 to 16 - ESP32 Platform from 2024.11.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.241030 to v3.1.0.241117 and IDF to 5.3.1.241024 (#22504) - Prevent active BLE operations with unencrypted MI-format beacons (#22453) +- Replace NeoPixelBus with TasmotaLED on ESP32x ### Fixed - ESP32 upgrade by file upload response based on file size (#22500) diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h index a86b05330..d26aece56 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h @@ -69,7 +69,7 @@ typedef struct { rmt_symbol_word_t reset_code; } rmt_led_strip_encoder_t; -static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +static IRAM_ATTR size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; diff --git a/lib/lib_basic/TasmotaLED/library.json b/lib/lib_basic/TasmotaLED/library.json new file mode 100644 index 000000000..8ee6079f5 --- /dev/null +++ b/lib/lib_basic/TasmotaLED/library.json @@ -0,0 +1,17 @@ +{ + "name": "TasmotaLED", + "version": "0.1", + "keywords": [ + "ws2816", "sk6812", "leds" + ], + "description": "Lightweight implementation for adressable leds.", + "repository": + { + "type": "git", + "url": "https://github.com/arendst/Tasmota/lib/lib_basic/TasmotaLED" + }, + "frameworks": "arduino", + "platforms": [ + "espressif32" + ] +} diff --git a/lib/lib_basic/TasmotaLED/src/TasmotaLED.cpp b/lib/lib_basic/TasmotaLED/src/TasmotaLED.cpp new file mode 100644 index 000000000..d323c20ab --- /dev/null +++ b/lib/lib_basic/TasmotaLED/src/TasmotaLED.cpp @@ -0,0 +1,237 @@ +/* + TasmotaLED.cpp - Lightweight implementation for adressable leds. + + Copyright (C) 2024 Stephan Hadinger + + This library 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 . +*/ + +#include +#ifdef ESP32 + +#include "TasmotaLEDPusher.h" +#include "TasmotaLED.h" + +// DRAM_ATTR to force in IRAM because we use this in show loop +static const DRAM_ATTR uint8_t TASMOTALED_CHANNEL_ORDERS[6][3] = { + {1, 0, 2}, // GRB (0) + {2, 0, 1}, // GBR (1) + {0, 1, 2}, // RGB (2) + {0, 2, 1}, // RBG (3) + {2, 1, 0}, // BRG (4) + {1, 2, 0} // BGR (5) +}; + +static const TasmotaLED_Timing TasmotaLED_Timings[] = { + // WS2812 + // RmtBit0 0x00228010 RmtBit1 0x00128020 RmtReset 0x800207D0 + { + .T0H = 400, + .T0L = 850, + .T1H = 800, + .T1L = 450, + .Reset = 80000 // it is 50000 for WS2812, but for compatibility with SK6812, we raise to 80000 + }, + // SK6812 + // RmtBit0 0x0024800C RmtBit1 0x00188018 RmtReset 0x80020C80 + { + .T0H = 300, + .T0L = 900, + .T1H = 600, + .T1L = 600, + .Reset = 80000 + }, +}; + +// enable AddLog +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); +enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; + + +TasmotaLED::TasmotaLED(uint16_t type, uint16_t num_leds) : + _type(type), + _pixel_order((type >> 4) & 0x07), + _w_before(type & 0x08), + _timing((type >> 8) & 0xFF), + _started(false), + _dirty(true), + _raw_format(false), + _pixel_count(num_leds), + _buf_work(nullptr), + _buf_show(nullptr), + _pixel_matrix(&TASMOTALED_CHANNEL_ORDERS[0]), + _pusher(nullptr) +{ + if (_timing > (TasmotaLed_TimingEnd >> 8)) { + _timing = 0; + } + switch (_type & 0x0F) { + // case TasmotaLed_1_W: + // _pixel_size = 1; + // break; + case TasmotaLed_4_WRGB: + _pixel_size = 4; + break; + case TasmotaLed_3_RGB: + default: // fallback + _pixel_size = 3; + break; + } + + _pixel_matrix = &TASMOTALED_CHANNEL_ORDERS[_pixel_order]; + + _buf_work = new uint8_t[_pixel_count * _pixel_size]; + memset(_buf_work, 0, _pixel_count * _pixel_size); + _buf_show = new uint8_t[_pixel_count * _pixel_size]; + memset(_buf_show, 0, _pixel_count * _pixel_size); + // AddLog(LOG_LEVEL_DEBUG, "LED: type=0x%04X pixel_order=0x%02X _timing=%i ", _type, _pixel_order, _timing); +} + +TasmotaLED::~TasmotaLED() { + if (_pusher) { + delete _pusher; + _pusher = nullptr; + } + delete _buf_work; + _buf_work = nullptr; + delete _buf_show; + _buf_show = nullptr; +} + +// Color is passed as 0xWWRRGGBB and copied as WWRRGGBB in _buf_work +void TasmotaLED::ClearTo(uint32_t wrgb, int32_t first, int32_t last) { + // adjust first and last to be in range of 0 to _pixel_count-1 + if (first <0) { first += _pixel_count; } + if (last <0) { last += _pixel_count; } + if (first < 0) { first = 0; } + if (last >= _pixel_count) { last = _pixel_count - 1; } + if (first > last) { return; } + // adjust to pixel format + uint8_t b0 = (wrgb >> 24) & 0xFF; + uint8_t b1 = (wrgb >> 16) & 0xFF; + uint8_t b2 = (wrgb >> 8) & 0xFF; + uint8_t b3 = (wrgb ) & 0xFF; + + if ((b0 | b1 | b2 | b3) == 0) { + // special version for clearing to black + memset(_buf_work + first * _pixel_size, 0, (last - first + 1) * _pixel_size); + } else { + // fill sub-buffer with RRGGBB or WWRRGGBB (or raw) + uint8_t *buf = _buf_work + first * _pixel_size; + for (uint32_t i = first; i <= last; i++) { + if (_pixel_size == 4) { *buf++ = b0;} + *buf++ = b1; + *buf++ = b2; + *buf++ = b3; + } + } +} + +void TasmotaLED::Show(void) { + if (_pusher) { + _dirty = false; // we don't use the _dirty attribute and always show + + // copy the input buffer to the work buffer in format to be understood by LED strip + if (_raw_format) { + memmove(_buf_show, _buf_work, _pixel_count * _pixel_size); // copy buffer in next buffer so we start with the current content + } else { + uint8_t *buf_from = _buf_work; + uint8_t *buf_to = _buf_show; + if (_pixel_size == 3) { + // copying with swapping 512 pixels (1536 bytes) takes 124 microseconds to copy, so it's negligeable + for (uint32_t i = 0; i < _pixel_count; i++) { + buf_to[(*_pixel_matrix)[0]] = buf_from[0]; // R + buf_to[(*_pixel_matrix)[1]] = buf_from[1]; // G + buf_to[(*_pixel_matrix)[2]] = buf_from[2]; // B + buf_to += 3; + buf_from += 3; + } + } else if (_pixel_size == 4) { + for (uint32_t i = 0; i < _pixel_count; i++) { + if (_w_before) { *buf_to++ = buf_from[3]; } + buf_to[(*_pixel_matrix)[0]] = buf_from[0]; // R + buf_to[(*_pixel_matrix)[1]] = buf_from[1]; // G + buf_to[(*_pixel_matrix)[2]] = buf_from[2]; // B + if (!_w_before) { *buf_to++ = buf_from[3]; } + buf_to += 3; // one increment already happened + buf_from += 4; + } + } + } + _pusher->Push(_buf_show); // push to leds + } +} + +void TasmotaLED::SetPixelColor(int32_t index, uint32_t wrgb) { + if (index < 0) { index += _pixel_count; } + if ((index >= 0) && (index < _pixel_count)) { + uint8_t *buf = _buf_work + index * _pixel_size; + uint8_t b0 = (wrgb >> 24) & 0xFF; + uint8_t b1 = (wrgb >> 16) & 0xFF; + uint8_t b2 = (wrgb >> 8) & 0xFF; + uint8_t b3 = (wrgb ) & 0xFF; + + if (_pixel_size == 4) { *buf++ = b0;} + *buf++ = b1; + *buf++ = b2; + *buf++ = b3; + _dirty = true; + } +} + +uint32_t TasmotaLED::GetPixelColor(int32_t index) { + if (index < 0) { index += _pixel_count; } + if ((index >= 0) && (index < _pixel_count)) { + uint8_t *buf = _buf_work + index * _pixel_size; + uint32_t wrgb = 0; + if (_pixel_size == 4) { wrgb = (*buf++) << 24; } + wrgb |= (*buf++) << 16; + wrgb |= (*buf++) << 8; + wrgb |= (*buf++); + return wrgb; + } else { + return 0; + } +} + +void TasmotaLED::SetPusher(TasmotaLEDPusher *pusher) { + if (_pusher) { + delete _pusher; + } + _pusher = pusher; + _started = false; +} + +bool TasmotaLED::Begin(void) { + if (_pusher) { + if (_started) { + return true; + } else { + const TasmotaLED_Timing * timing = &TasmotaLED_Timings[_timing]; + // AddLog(LOG_LEVEL_DEBUG, "LED: T0H=%i T0L=%i T1H=%i T1L=%i Reset=%i", timing.T0H, timing.T0L, timing.T1H, timing.T1L, timing.Reset); + return _pusher->Begin(_pixel_count, _pixel_size, timing); + } + } else { + return false; + } +} + +bool TasmotaLED::CanShow(void) const { + if (_pusher) { + return _pusher->CanShow(); + } + return false; +} + +#endif // ESP32 diff --git a/lib/lib_basic/TasmotaLED/src/TasmotaLED.h b/lib/lib_basic/TasmotaLED/src/TasmotaLED.h new file mode 100644 index 000000000..ac1b78c1e --- /dev/null +++ b/lib/lib_basic/TasmotaLED/src/TasmotaLED.h @@ -0,0 +1,129 @@ +/* + TasmotaLED.h - Lightweight implementation for adressable leds. + + Copyright (C) 2024 Stephan Hadinger + + This library 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 . +*/ + +#ifndef __TASMOTALED_H__ +#define __TASMOTALED_H__ + +enum TasmotaLEDTypesEncoding : uint16_t { + // bits 0..3 encode for number of bytes per pixel + TasmotaLed_1_W = 0x0, // 1 byte per pixel (not used yet) + TasmotaLed_3_RGB = 0x1, // 3 bytes per pixel + TasmotaLed_4_WRGB = 0x2, // 4 bytes per pixel + // bits 4..6 encode for pixel order + TasmotaLed_GRB = 0b000 << 4, + TasmotaLed_GBR = 0b001 << 4, + TasmotaLed_RGB = 0b010 << 4, + TasmotaLed_RBG = 0b011 << 4, + TasmotaLed_BRG = 0b100 << 4, + TasmotaLed_BGR = 0b101 << 4, + // bit 7 sets the position for W channel + TasmotaLed_xxxW = 0b0 << 7, // W channel after color + TasmotaLed_Wxxx = 0b1 << 7, // W channel before color + // bits 8..15 encode for timing specifics + TasmotaLed_WS2812 = 0 << 8, + TasmotaLed_SK6812 = 1 << 8, + TasmotaLed_TimingEnd = 2 << 8, +}; + +enum TasmotaLEDHardware : uint32_t { + // low-order bits are reserved for channels numbers and hardware flags - currenlty not useds + // bits 16..23 + TasmotaLed_HW_Default = 0x0 << 16, + TasmotaLed_RMT = 1 << 16, + TasmotaLed_SPI = 2 << 16, + TasmotaLed_I2S = 3 << 16, + TasmotaLed_HW_None = 0xFF << 16, // indicates that the specified HW is not supported +}; + +// Below is the encoding for full strips +// We need to keep backwards compatibility so: +// 0 = WS2812 (GRB) +// 1 = SK6812 with White (GRBW) +enum TasmotaLEDTypes : uint16_t { + ws2812_grb = TasmotaLed_3_RGB | TasmotaLed_GRB | TasmotaLed_WS2812, // 1 for backwards compatibility + sk6812_grbw = TasmotaLed_4_WRGB | TasmotaLed_GRB | TasmotaLed_xxxW | TasmotaLed_SK6812, // 2 for backwards compatibility + sk6812_grb = TasmotaLed_3_RGB | TasmotaLed_GRB | TasmotaLed_SK6812, +}; + +#ifdef __cplusplus + +/*******************************************************************************************\ + * class TasmotaLED + * + * This class is a lightweight replacement for NeoPixelBus library with a smaller + * implementation focusing only on pushing a buffer to the leds. + * + * It supports: + * - RMT and I2S hardware support + * Possible enhancements could be considered with SPI and Serial + * - Led size of 3 bytes (GRB) and 4 bytes (GRBW) + * APIs take 0xRRGGBB or 0xRRGGBBWW as input + * but Internal buffers use GGRRBB and GGRRBBWW + * - Led type of WS2812 and SK6812 + * - There is no buffer swapping, the working buffer is copied to an internal + * buffer just before display, so you can keep a reference to the buffer + * and modify it without having to worry about the display + * - buffer is cleared at start + * - "Dirty" is kept for API compatibility with NeoPixelBus but is glbally ignored + * so any call to `Show()` pushes the pixels even if they haven't changed. + * Control for dirty pixels should be done by the caller if required. + * - We tried to keep as close as possible to NeoPixelBus method names to ease transition +\*******************************************************************************************/ +class TasmotaLEDPusher; // forward definition +class TasmotaLED { +public: + TasmotaLED(uint16_t type, uint16_t num_leds); + ~TasmotaLED(); + + bool Begin(void); + void SetPusher(TasmotaLEDPusher *pusher); // needs to be called before `Begin()`, sets the hardware implementation + void Show(void); // pushes the pixels to the LED strip + inline void SetRawFormat(bool raw_format) { _raw_format = raw_format; } + + void ClearTo(uint32_t rgbw, int32_t first = 0, int32_t last = -1); + void SetPixelColor(int32_t index, uint32_t wrgb); + uint32_t GetPixelColor(int32_t index); + + uint8_t GetType(void) const { return _type; } + uint16_t PixelCount(void) const { return _pixel_count; } + uint8_t PixelSize(void) const { return _pixel_size; } + inline uint8_t * Pixels(void) const { return _buf_work; } + inline bool IsDirty(void) const { return _dirty; } + inline void Dirty(void) { _dirty = true; } + + bool CanShow(void) const; + +protected: + uint16_t _type; // the composite type + uint8_t _pixel_order; // permutation between RGB and position of W + bool _w_before; // true if W channel comes first (4 channels only) + uint8_t _timing; // timing code for strip, 0=WS2812, 1=SK6812... + bool _started; // true if the hardware implementation is configured + bool _dirty; // for NeoPixelBus compatibility, but ignored by `Push()` + bool _raw_format; // if true, copy raw to leds, if false, convert from RGB to GRB or LED format + uint16_t _pixel_count; // how many pixels in the strip + uint8_t _pixel_size; // how many bytes per pixels, only 3 and 4 are supported + uint8_t *_buf_work; // buffer used to draw into, can be modified directly by the caller + uint8_t *_buf_show; // copy of the buffer used to push to leds, private to this class + const uint8_t (*_pixel_matrix)[3]; // pointer to the pixer_order_matrix + TasmotaLEDPusher *_pusher; // pixels pusher implementation based on hardware (RMT, I2S...) +}; + +#endif // __cplusplus +#endif // __TASMOTALED_H__ diff --git a/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.cpp b/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.cpp new file mode 100644 index 000000000..d765703e5 --- /dev/null +++ b/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.cpp @@ -0,0 +1,97 @@ +/* + TasmotaLEDPusher.cpp - Implementation to push Leds via hardware acceleration + + Copyright (C) 2024 Stephan Hadinger + + This library 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 ESP32 + +#include "TasmotaLEDPusher.h" +#include "TasmotaLED.h" + +//************************************************************************************************************** +// enable AddLog support within a C++ library +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); +enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; +//************************************************************************************************************** + + +// convert to the appropriate hardware acceleration based on capacities of the SOC +uint32_t TasmotaLEDPusher::ResolveHardware(uint32_t hw) { +uint32_t hw_orig = hw; + // Step 1. discard any unsupported hardware, and replace with TasmotaLed_HW_Default + uint32_t hw_type = hw & 0xFF0000; // discard bits 0..15 +#if !TASMOTALED_HARDWARE_RMT + if (hw_type == TasmotaLed_RMT) { + hw = TasmotaLed_HW_None; + } +#endif // TASMOTALED_HARDWARE_RMT +#if !TASMOTALED_HARDWARE_SPI + if (hw_type == TasmotaLed_SPI) { + hw = TasmotaLed_HW_None; + } +#endif // TASMOTALED_HARDWARE_SPI +#if !TASMOTALED_HARDWARE_I2S + if (hw_type == TasmotaLed_I2S) { + hw = TasmotaLed_HW_None; + } +#endif // TASMOTALED_HARDWARE_I2S + + // Step 2. If TasmotaLed_HW_Default, find a suitable scheme, RMT preferred +#if TASMOTALED_HARDWARE_RMT + if ((hw & 0xFF0000) == TasmotaLed_HW_Default) { + hw = TasmotaLed_RMT; + } +#endif // TASMOTALED_HARDWARE_RMT +#if TASMOTALED_HARDWARE_I2S + if ((hw & 0xFF0000) == TasmotaLed_HW_Default) { + hw = TasmotaLed_I2S; + } +#endif // TASMOTALED_HARDWARE_I2S +#if TASMOTALED_HARDWARE_SPI + if ((hw & 0xFF0000) == TasmotaLed_HW_Default) { + hw = TasmotaLed_SPI; + } +#endif // TASMOTALED_HARDWARE_SPI + return hw; +} + + +TasmotaLEDPusher * TasmotaLEDPusher::Create(uint32_t hw, int8_t gpio) { + TasmotaLEDPusher * pusher = nullptr; + + hw = TasmotaLEDPusher::ResolveHardware(hw); + + switch (hw & 0XFF0000) { +#if TASMOTALED_HARDWARE_RMT + case TasmotaLed_RMT: + pusher = new TasmotaLEDPusherRMT(gpio); + AddLog(LOG_LEVEL_DEBUG, "LED: RMT gpio %i", gpio); + break; +#endif // TASMOTALED_HARDWARE_RMT +#if TASMOTALED_HARDWARE_SPI + case TasmotaLed_SPI: + pusher = new TasmotaLEDPusherSPI(gpio); + AddLog(LOG_LEVEL_DEBUG, "LED: SPI gpio %i", gpio); + break; +#endif // TASMOTALED_HARDWARE_SPI + default: + break; + } + return pusher; +} + +#endif // ESP32 diff --git a/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.h b/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.h new file mode 100644 index 000000000..2b8eb4896 --- /dev/null +++ b/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.h @@ -0,0 +1,161 @@ +/* + TasmotaLEDPusher.h - Abstract class for Leds pusher (RMT, SPI, I2S...) + + Copyright (C) 2024 Stephan Hadinger + + This library 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 . +*/ + +#ifndef __TASMOTALEDPUSHER_H__ +#define __TASMOTALEDPUSHER_H__ + +#include + +// Below are flags to enable of disable each hardware support: RMT, I2S, SPI +// By default, only enable RMT support, and SPI is used as fallback if no protocol works +// +// Use de defines below: +// #define TASMOTALED_HARDWARE_RMT 0/1 +// #define TASMOTALED_HARDWARE_I2S 0/1 +// #define TASMOTALED_HARDWARE_SPI 0/1 +// +#ifndef TASMOTALED_HARDWARE_RMT + #define TASMOTALED_HARDWARE_RMT 1 +#endif + +#ifndef TASMOTALED_HARDWARE_I2S + #define TASMOTALED_HARDWARE_I2S 0 +#endif + +#ifndef TASMOTALED_HARDWARE_SPI + #define TASMOTALED_HARDWARE_SPI 0 +#endif + +// Disable any hardware if not supported by the SOC +#if TASMOTALED_HARDWARE_RMT && !defined(SOC_RMT_SUPPORTED) + #undef TASMOTALED_HARDWARE_RMT + #define TASMOTALED_HARDWARE_RMT 0 +#endif + +#if TASMOTALED_HARDWARE_I2S && !defined(SOC_I2S_SUPPORTED) + #undef TASMOTALED_HARDWARE_I2S + #define TASMOTALED_HARDWARE_I2S 0 +#endif + +#if TASMOTALED_HARDWARE_SPI && !defined(SOC_GPSPI_SUPPORTED) + #undef TASMOTALED_HARDWARE_SPI + #define TASMOTALED_HARDWARE_SPI 0 +#endif + +// if no protocol is defined, use SPI as fallback +#if !TASMOTALED_HARDWARE_RMT && !TASMOTALED_HARDWARE_I2S && !TASMOTALED_HARDWARE_SPI + #undef TASMOTALED_HARDWARE_SPI + #define TASMOTALED_HARDWARE_SPI 1 +#endif + +// Timing structure for LEDS - in nanoseconds +// It is passed by TasmotaLed to the pushers +typedef struct TasmotaLED_Timing { + uint16_t T0H, T0L, T1H, T1L; + uint32_t Reset; +} TasmotaLED_Timing; + +/*******************************************************************************************\ + * class TasmotaLEDPusher + * + * This is an virtual abstract class for Leds pusher (RMT, SPI, I2S...) + * + * Below are interfaces for current implementations +\*******************************************************************************************/ +class TasmotaLEDPusher { +public: + TasmotaLEDPusher() : _pixel_count(0), _pixel_size(0), _led_timing(nullptr) {}; + virtual ~TasmotaLEDPusher() {}; + + virtual bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) { + _pixel_count = pixel_count; + _pixel_size = pixel_size; + _led_timing = led_timing; + return true; + } + virtual bool Push(uint8_t *buf) = 0; + virtual bool CanShow(void) = 0; + + static uint32_t ResolveHardware(uint32_t hw); // convert to the appropriate hardware acceleration based on capacities of the SOC + static TasmotaLEDPusher * Create(uint32_t hw, int8_t gpio); // create instance for the provided type, or nullptr if failed + +protected: + uint16_t _pixel_count; + uint16_t _pixel_size; + const TasmotaLED_Timing * _led_timing; +}; + +/*******************************************************************************************\ + * class TasmotaLEDPusherRMT + * + * Implementation based on RMT driver +\*******************************************************************************************/ +#if TASMOTALED_HARDWARE_RMT +#include "driver/rmt_tx.h" +class TasmotaLEDPusherRMT : public TasmotaLEDPusher { +public: + TasmotaLEDPusherRMT(int8_t pin) : _pin(pin) {}; + ~TasmotaLEDPusherRMT(); + + bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override; + + bool Push(uint8_t *buf) override; + bool CanShow(void) override; +protected: + int8_t _pin; + rmt_transmit_config_t _tx_config = {}; + rmt_channel_handle_t _channel = nullptr;; + rmt_encoder_handle_t _led_encoder = nullptr; +}; +#endif // TASMOTALED_HARDWARE_RMT + +/*******************************************************************************************\ + * class TasmotaLEDPusherSPI + * + * Implementation based on SPI driver, mandatory for C2 +\*******************************************************************************************/ +#if TASMOTALED_HARDWARE_SPI +#include + +typedef struct led_strip_spi_obj_t { + uint8_t * pixel_buf; + uint16_t strip_len; + uint8_t bytes_per_pixel; + spi_host_device_t spi_host; + spi_device_handle_t spi_device; + spi_transaction_t tx_conf; // transaction in process if any +} led_strip_spi_obj; + +class TasmotaLEDPusherSPI : public TasmotaLEDPusher { +public: + TasmotaLEDPusherSPI(int8_t pin) : _pin(pin), _spi_strip({}) {}; + ~TasmotaLEDPusherSPI(); + + bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override; + + bool Push(uint8_t *buf) override; + bool CanShow(void) override; + +protected: + int8_t _pin; + struct led_strip_spi_obj_t _spi_strip; +}; +#endif // TASMOTALED_HARDWARE_SPI + +#endif // __TASMOTALEDPUSHER_H__ diff --git a/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusherRMT.cpp b/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusherRMT.cpp new file mode 100644 index 000000000..747985008 --- /dev/null +++ b/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusherRMT.cpp @@ -0,0 +1,240 @@ +/* + TasmotaLEDPusherRMT.cpp - Implementation to push Leds via RMT channel + + Copyright (C) 2024 Stephan Hadinger + + This library 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 ESP32 + +#include "TasmotaLEDPusher.h" +#include "TasmotaLED.h" + +#if TASMOTALED_HARDWARE_RMT +#include +#include + +//************************************************************************************************************** +// enable AddLog support within a C++ library +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); +enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; +//************************************************************************************************************** + +/*******************************************************************************************\ + * Implementation for TasmotaLEDPusherRMT + * + * Code mostly copied from Tasmota patch to NeoPixelBus applied to support esp-idf 5.x + * itself inspired from esp-idf example for RMT encoder from + * https://github.com/espressif/esp-idf/tree/v5.3.1/examples/peripherals/rmt/ir_nec_transceiver +\*******************************************************************************************/ +#define RMT_LED_STRIP_RESOLUTION_HZ 40000000 // 40MHz resolution, steps of 25 nanoseconds + +// structure used to pass arguments to `rmt_new_led_strip_encoder` +// currently only the encoder resolution in Hz +typedef struct { + uint32_t resolution; /*!< Encoder resolution, in Hz */ +} led_strip_encoder_config_t; + +// structure used to store all the necessary information for the RMT encoder +typedef struct { + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int32_t state; + rmt_symbol_word_t reset_code; +} rmt_led_strip_encoder_t; + +static IRAM_ATTR size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; + rmt_encode_state_t session_state = RMT_ENCODING_RESET; + rmt_encode_state_t state = RMT_ENCODING_RESET; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_MEM_FULL)); + goto out; // yield if there's no free space for encoding artifacts + } + // fall-through + case 1: // send reset code + encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = RMT_ENCODING_RESET; // back to the initial encoding session + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_COMPLETE)); + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_MEM_FULL)); + goto out; // yield if there's no free space for encoding artifacts + } + } +out: + *ret_state = state; + return encoded_symbols; +} + +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) { + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + delete led_encoder; + return ESP_OK; +} + +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) { + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = RMT_ENCODING_RESET; + return ESP_OK; +} + +static esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder, rmt_symbol_word_t bit0, rmt_symbol_word_t bit1, rmt_symbol_word_t reset_code) { + static const char* TAG = "TASMOTA_RMT"; + esp_err_t ret = ESP_OK; + rmt_led_strip_encoder_t *led_encoder = NULL; + rmt_bytes_encoder_config_t bytes_encoder_config; + rmt_copy_encoder_config_t copy_encoder_config = {}; + + ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + led_encoder = new rmt_led_strip_encoder_t(); + ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); + led_encoder->base.encode = rmt_encode_led_strip; + led_encoder->base.del = rmt_del_led_strip_encoder; + led_encoder->base.reset = rmt_led_strip_encoder_reset; + led_encoder->reset_code = reset_code; + + bytes_encoder_config.bit0 = bit0; + bytes_encoder_config.bit1 = bit1; + bytes_encoder_config.flags.msb_first = 1; // WS2812 transfer bit order: G7...G0R7...R0B7...B0 - TODO: more checks + + ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); + ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); + + *ret_encoder = &led_encoder->base; + return ret; +err: + AddLog(LOG_LEVEL_INFO, "RMT: could not init led encoder"); + if (led_encoder) { + if (led_encoder->bytes_encoder) { rmt_del_encoder(led_encoder->bytes_encoder); } + if (led_encoder->copy_encoder) { rmt_del_encoder(led_encoder->copy_encoder); } + delete led_encoder; + } + return ret; +} + +TasmotaLEDPusherRMT::~TasmotaLEDPusherRMT() { + if (_channel) { + rmt_tx_wait_all_done(_channel, 10000 / portTICK_PERIOD_MS); + rmt_del_channel(_channel); + _channel = nullptr; + } + + if (_pin >= 0) { + gpio_matrix_out(_pin, 0x100, false, false); + pinMode(_pin, INPUT); + _pin = -1; + } +} + +bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) { + TasmotaLEDPusher::Begin(pixel_count, pixel_size, led_timing); + + esp_err_t ret = ESP_OK; + rmt_tx_channel_config_t config = {}; + config.clk_src = RMT_CLK_SRC_DEFAULT; + config.gpio_num = static_cast(_pin); + config.mem_block_symbols = 192; // memory block size, 64 * 4 = 256 Bytes + config.resolution_hz = RMT_LED_STRIP_RESOLUTION_HZ; // 40 MHz tick resolution, i.e., 1 tick = 0.025 µs or 25 ns + config.trans_queue_depth = 4; // set the number of transactions that can pend in the background + config.flags.invert_out = false; // do not invert output signal + config.flags.with_dma = false; // do not need DMA backend + + ret = rmt_new_tx_channel(&config, &_channel); + if (ret != ESP_OK) { + AddLog(LOG_LEVEL_INFO, "RMT: cannot initialize Gpio %i err=%i", _pin, ret); + return false; + } + led_strip_encoder_config_t encoder_config = { + .resolution = RMT_LED_STRIP_RESOLUTION_HZ, + }; + + _tx_config.loop_count = 0; // no loop + + rmt_symbol_word_t RmtBit0 = { + .duration0 = (uint16_t) (led_timing->T0H * (RMT_LED_STRIP_RESOLUTION_HZ / 1000000) / 1000), + .level0 = 1, + .duration1 = (uint16_t) (led_timing->T0L * (RMT_LED_STRIP_RESOLUTION_HZ / 1000000) / 1000), + .level1 = 0, + }; + rmt_symbol_word_t RmtBit1 = { + .duration0 = (uint16_t) (led_timing->T1H * (RMT_LED_STRIP_RESOLUTION_HZ / 1000000) / 1000), + .level0 = 1, + .duration1 = (uint16_t) (led_timing->T1L * (RMT_LED_STRIP_RESOLUTION_HZ / 1000000) / 1000), + .level1 = 0, + }; + rmt_symbol_word_t RmtReset = { + .duration0 = (uint16_t) (led_timing->Reset * (RMT_LED_STRIP_RESOLUTION_HZ / 1000000) / 1000), + .level0 = 0, + .duration1 = 50 * (RMT_LED_STRIP_RESOLUTION_HZ / 1000000) / 1000, + .level1 = 1, + }; + // AddLog(LOG_LEVEL_INFO, "RMT: RmtBit0 0x%08X RmtBit1 0x%08X RmtReset 0x%08X", RmtBit0.val, RmtBit1.val, RmtReset.val); + ret = rmt_new_led_strip_encoder(&encoder_config, &_led_encoder, RmtBit0, RmtBit1, RmtReset); + if (ret != ESP_OK) { + // AddLog(LOG_LEVEL_INFO, "RMT: cannot initialize led strip encoder err=%i", ret); + return false; + } + ret = rmt_enable(_channel); + if (ret != ESP_OK) { + // AddLog(LOG_LEVEL_INFO, "RMT: cannot enable channel err=%i", ret); + return false; + } + return true; +} + +bool TasmotaLEDPusherRMT::CanShow(void) { + if (_channel) { + return (ESP_OK == rmt_tx_wait_all_done(_channel, 0)); + } else { + return false; + } +} + +bool TasmotaLEDPusherRMT::Push(uint8_t *buf) { + + // wait for not actively sending data + // this will time out at 1 second, an arbitrarily long period of time + // and do nothing if this happens + esp_err_t ret = rmt_tx_wait_all_done(_channel, 1000 / portTICK_PERIOD_MS); + if (ESP_OK == ret) { + // now start the RMT transmit with the editing buffer before we swap + ret = rmt_transmit(_channel, _led_encoder, buf, _pixel_count * _pixel_size, &_tx_config); + if (ESP_OK != ret) { + AddLog(LOG_LEVEL_DEBUG, "RMT: cannot transmit err=%i", ret); + return false; + } + } + return true; +} + +#endif // TASMOTALED_HARDWARE_RMT +#endif // ESP32 diff --git a/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusherSPI.cpp b/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusherSPI.cpp new file mode 100644 index 000000000..72ea342ef --- /dev/null +++ b/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusherSPI.cpp @@ -0,0 +1,191 @@ +/* + TasmotaLEDPusherRMT.cpp - Implementation to push Leds via SPI channel + + Copyright (C) 2024 Stephan Hadinger + + This library 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 ESP32 + +#include "TasmotaLEDPusher.h" +#include "TasmotaLED.h" + +#if TASMOTALED_HARDWARE_SPI +#include + +//************************************************************************************************************** +// enable AddLog support within a C++ library +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); +enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; +//************************************************************************************************************** + +/*******************************************************************************************\ + * Implementation for TasmotaLEDPusherSPI + * +\*******************************************************************************************/ + +#define LED_STRIP_SPI_DEFAULT_RESOLUTION (25 * 100 * 1000) // 2.5MHz resolution +#define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4 + +#define SPI_BYTES_PER_COLOR_BYTE 3 +#define SPI_BITS_PER_COLOR_BYTE (SPI_BYTES_PER_COLOR_BYTE * 8) + +static void __led_strip_spi_bit(uint8_t data, uint8_t *buf) +{ + // Each color of 1 bit is represented by 3 bits of SPI, low_level:100 ,high_level:110 + // So a color byte occupies 3 bytes of SPI. + buf[0] = (data & BIT(5) ? BIT(1) | BIT(0) : BIT(1)) | (data & BIT(6) ? BIT(4) | BIT(3) : BIT(4)) | (data & BIT(7) ? BIT(7) | BIT(6) : BIT(7)); + buf[1] = (BIT(0)) | (data & BIT(3) ? BIT(3) | BIT(2) : BIT(3)) | (data & BIT(4) ? BIT(6) | BIT(5) : BIT(6)); + buf[2] = (data & BIT(0) ? BIT(2) | BIT(1) : BIT(2)) | (data & BIT(1) ? BIT(5) | BIT(4) : BIT(5)) | (data & BIT(2) ? BIT(7) : 0x00); +} + +esp_err_t led_strip_spi_refresh(led_strip_spi_obj * spi_strip) +{ + spi_strip->tx_conf.length = spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BITS_PER_COLOR_BYTE; + spi_strip->tx_conf.tx_buffer = spi_strip->pixel_buf; + spi_strip->tx_conf.rx_buffer = NULL; + spi_device_transmit(spi_strip->spi_device, &spi_strip->tx_conf); + return ESP_OK; +} + +void led_strip_transmit_buffer(led_strip_spi_obj * spi_strip, uint8_t * buffer_rgbw) { + // Timing for 512 pixels (extreme test) + // Copying to buffer: 418 us + // sending pixels: 16.2 ms + uint8_t * buf = buffer_rgbw; + uint8_t * pix_buf = spi_strip->pixel_buf; + for (int i = 0; i < spi_strip->strip_len; i++) { + // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes) + __led_strip_spi_bit(*buf++, pix_buf); pix_buf += SPI_BYTES_PER_COLOR_BYTE; + __led_strip_spi_bit(*buf++, pix_buf); pix_buf += SPI_BYTES_PER_COLOR_BYTE; + __led_strip_spi_bit(*buf++, pix_buf); pix_buf += SPI_BYTES_PER_COLOR_BYTE; + if (spi_strip->bytes_per_pixel > 3) { + __led_strip_spi_bit(*buf++, pix_buf); pix_buf += SPI_BYTES_PER_COLOR_BYTE; + } + } + /* Refresh the strip to send data */ + led_strip_spi_refresh(spi_strip); +} + + +TasmotaLEDPusherSPI::~TasmotaLEDPusherSPI() { + if (_spi_strip.spi_device) { + spi_bus_remove_device(_spi_strip.spi_device); + } + if (_spi_strip.spi_host) { + spi_bus_free(_spi_strip.spi_host); + } + + if (_pin >= 0) { + gpio_matrix_out(_pin, 0x100, false, false); + pinMode(_pin, INPUT); + _pin = -1; + } +} + +bool TasmotaLEDPusherSPI::Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) { + TasmotaLEDPusher::Begin(pixel_count, pixel_size, led_timing); + _spi_strip.bytes_per_pixel = _pixel_size; + _spi_strip.strip_len = _pixel_count; + + esp_err_t err = ESP_OK; + uint32_t mem_caps = MALLOC_CAP_DEFAULT; + // spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; + spi_bus_config_t spi_bus_cfg; + spi_device_interface_config_t spi_dev_cfg; + spi_host_device_t spi_host = SPI2_HOST; + bool with_dma = true; /// TODO: pass value or compute based on pixelcount + int clock_resolution_khz = 0; + + if (with_dma) { // TODO + // DMA buffer must be placed in internal SRAM + mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; + } + _spi_strip.pixel_buf = (uint8_t *)heap_caps_calloc(1, _pixel_count * _pixel_size * SPI_BYTES_PER_COLOR_BYTE, mem_caps); + if (_spi_strip.pixel_buf == nullptr) { + AddLog(LOG_LEVEL_INFO, PSTR("LED: Error no mem for spi strip")); + goto err; + } + + spi_bus_cfg = { + .mosi_io_num = _pin, + //Only use MOSI to generate the signal, set -1 when other pins are not used. + .miso_io_num = -1, + .sclk_io_num = -1, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = _pixel_count * _pixel_size * SPI_BYTES_PER_COLOR_BYTE, + }; + err = spi_bus_initialize(spi_host, &spi_bus_cfg, with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED); + if (err != ESP_OK) { + AddLog(LOG_LEVEL_INFO, PSTR("LED: Error create SPI bus failed")); + goto err; + } + _spi_strip.spi_host = spi_host; // confirmed working, so keep it's value to free it later + + spi_dev_cfg = { + .command_bits = 0, + .address_bits = 0, + .dummy_bits = 0, + .mode = 0, + //set -1 when CS is not used + .clock_source = SPI_CLK_SRC_DEFAULT, // clk_src, + .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION, + .spics_io_num = -1, + .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, + }; + err = spi_bus_add_device(_spi_strip.spi_host, &spi_dev_cfg, &_spi_strip.spi_device); + if (err != ESP_OK) { + // AddLog(LOG_LEVEL_INFO, "LED: Error failed to add spi device"); + goto err; + } + + spi_device_get_actual_freq(_spi_strip.spi_device, &clock_resolution_khz); + if (err != ESP_OK) { + // AddLog(LOG_LEVEL_INFO, "LED: Error failed to get spi frequency"); + goto err; + } + // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real clock resolution + // But now, let's fixed the resolution, the downside is, we don't support a clock source whose frequency is not multiple of LED_STRIP_SPI_DEFAULT_RESOLUTION + if (clock_resolution_khz != LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000) { + // AddLog(LOG_LEVEL_INFO, "LED: Error unsupported clock resolution: %dKHz", clock_resolution_khz); + goto err; + } + + return true; +err: + if (_spi_strip.spi_device) { + spi_bus_remove_device(_spi_strip.spi_device); + } + if (_spi_strip.spi_host) { + spi_bus_free(_spi_strip.spi_host); + } + return false; +} + +bool TasmotaLEDPusherSPI::CanShow(void) { + return true; // TODO +} + +bool TasmotaLEDPusherSPI::Push(uint8_t *buf) { + + if (CanShow()) { + led_strip_transmit_buffer(&_spi_strip, buf); + } + return true; +} + +#endif // TASMOTALED_HARDWARE_SPI +#endif // ESP32 diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c index e4f60edcc..f948b7d04 100644 --- a/lib/libesp32/berry/default/be_modtab.c +++ b/lib/libesp32/berry/default/be_modtab.c @@ -152,7 +152,7 @@ BERRY_LOCAL const bntvmodule_t* const be_module_table[] = { &be_native_module(unishox), #endif // USE_UNISHOX_COMPRESSION -#ifdef USE_WS2812 +#if defined(USE_WS2812) && !defined(USE_WS2812_FORCE_NEOPIXELBUS) &be_native_module(animate), #endif // USE_WS2812 @@ -293,7 +293,7 @@ BERRY_LOCAL bclass_array be_class_table = { #ifdef USE_BERRY_TCPSERVER &be_native_class(tcpserver), #endif // USE_BERRY_TCPSERVER -#ifdef USE_WS2812 +#if defined(USE_WS2812) && !defined(USE_WS2812_FORCE_NEOPIXELBUS) &be_native_class(Leds_ntv), &be_native_class(Leds), #endif // USE_WS2812 diff --git a/lib/libesp32/berry_animate/src/be_berry_leds_frame.cpp b/lib/libesp32/berry_animate/src/be_berry_leds_frame.cpp index 70917593f..65ab158cc 100644 --- a/lib/libesp32/berry_animate/src/be_berry_leds_frame.cpp +++ b/lib/libesp32/berry_animate/src/be_berry_leds_frame.cpp @@ -45,10 +45,10 @@ extern "C" { uint32_t g2 = (color_b >> 8) & 0xFF; uint32_t b2 = (color_b ) & 0xFF; uint32_t a2 = (color_b >> 24) & 0xFF; - uint32_t r3 = changeUIntScale(alpha, 0, 255, r2, r); - uint32_t g3 = changeUIntScale(alpha, 0, 255, g2, g); - uint32_t b3 = changeUIntScale(alpha, 0, 255, b2, b); - uint32_t a3 = changeUIntScale(alpha, 0, 255, a2, a); + uint8_t r3 = changeUIntScale(alpha, 0, 255, r2, r); + uint8_t g3 = changeUIntScale(alpha, 0, 255, g2, g); + uint8_t b3 = changeUIntScale(alpha, 0, 255, b2, b); + uint8_t a3 = changeUIntScale(alpha, 0, 255, a2, a); uint32_t rgb = (a3 << 24) | (r3 << 16) | (g3 << 8) | b3; be_pushint(vm, rgb); be_return(vm); @@ -97,9 +97,9 @@ extern "C" { uint32_t fore_g = (fore_argb >> 8) & 0xFF; uint32_t back_b = (back_argb ) & 0xFF; uint32_t fore_b = (fore_argb ) & 0xFF; - uint32_t dest_r_new = changeUIntScale(fore_alpha, 0, 255, fore_r, back_r); - uint32_t dest_g_new = changeUIntScale(fore_alpha, 0, 255, fore_g, back_g); - uint32_t dest_b_new = changeUIntScale(fore_alpha, 0, 255, fore_b, back_b); + uint8_t dest_r_new = changeUIntScale(fore_alpha, 0, 255, fore_r, back_r); + uint8_t dest_g_new = changeUIntScale(fore_alpha, 0, 255, fore_g, back_g); + uint8_t dest_b_new = changeUIntScale(fore_alpha, 0, 255, fore_b, back_b); dest_rgb_new = (dest_r_new << 16) | (dest_g_new << 8) | dest_b_new; } dest[i] = dest_rgb_new; @@ -135,7 +135,7 @@ extern "C" { // Leds_frame.paste_pixels(neopixel:bytes(), led_buffer:bytes(), bri:int 0..100, gamma:bool) // - // Copy from ARGB buffer to GRB + // Copy from ARGB buffer to RGB int32_t be_leds_paste_pixels(bvm *vm); int32_t be_leds_paste_pixels(bvm *vm) { int32_t top = be_top(vm); // Get the number of arguments @@ -162,8 +162,8 @@ extern "C" { uint32_t src_r = (src_argb >> 16) & 0xFF; uint32_t src_g = (src_argb >> 8) & 0xFF; uint32_t src_b = (src_argb ) & 0xFF; - dest_buf[i * 3 + 0] = src_g; - dest_buf[i * 3 + 1] = src_r; + dest_buf[i * 3 + 0] = src_r; + dest_buf[i * 3 + 1] = src_g; dest_buf[i * 3 + 2] = src_b; } } diff --git a/lib/libesp32/berry_tasmota/src/be_leds_ntv_lib.c b/lib/libesp32/berry_tasmota/src/be_leds_ntv_lib.c index 26ff0b69b..11b2712f6 100644 --- a/lib/libesp32/berry_tasmota/src/be_leds_ntv_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_leds_ntv_lib.c @@ -7,7 +7,9 @@ #ifdef USE_WS2812 -extern int be_neopixelbus_call_native(bvm *vm); +#include "TasmotaLED.h" + +extern int be_tasmotaled_call_native(bvm *vm); extern int be_leds_blend_color(bvm *vm); extern int be_leds_apply_bri_gamma(bvm *vm); @@ -16,10 +18,15 @@ class be_class_Leds_ntv (scope: global, name: Leds_ntv, strings: weak) { _p, var _t, var - WS2812_GRB, int(1) - SK6812_GRBW, int(2) + WS2812_GRB, int(ws2812_grb) + SK6812_GRBW, int(sk6812_grbw) + SK6812_GRB, int(sk6812_grb) - call_native, func(be_neopixelbus_call_native) + RMT, int(TasmotaLed_RMT) + SPI, int(TasmotaLed_SPI) + I2S, int(TasmotaLed_I2S) + + call_native, func(be_tasmotaled_call_native) blend_color, static_func(be_leds_blend_color) apply_bri_gamma, static_func(be_leds_apply_bri_gamma) diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds.be b/lib/libesp32/berry_tasmota/src/embedded/leds.be index 019a64e3b..7a124fc50 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/leds.be +++ b/lib/libesp32/berry_tasmota/src/embedded/leds.be @@ -31,8 +31,8 @@ class Leds : Leds_ntv # leds:int = number of leds of the strip # gpio:int (optional) = GPIO for NeoPixel. If not specified, takes the WS2812 gpio # typ:int (optional) = Type of LED, defaults to WS2812 RGB - # rmt:int (optional) = RMT hardware channel to use, leave default unless you have a good reason - def init(leds, gpio_phy, typ, rmt) # rmt is optional + # hardware:int (optional) = hardware support (Leds.RMT, Leds.SPI) + def init(leds, gpio_phy, typ, hardware) import gpio self.gamma = true # gamma is enabled by default, it should be disabled explicitly if needed if (gpio_phy == nil) || (gpio_phy == gpio.pin(gpio.WS2812, 0)) @@ -47,7 +47,7 @@ class Leds : Leds_ntv self.bri = 127 # 50% brightness by default # initialize the structure - self.ctor(self.leds, gpio_phy, typ, rmt) + self.ctor(self.leds, gpio_phy, typ, hardware) end if self._p == nil raise "internal_error", "couldn't not initialize noepixelbus" end @@ -56,44 +56,6 @@ class Leds : Leds_ntv self.begin() end - # assign RMT - static def assign_rmt(gpio_phy) - gpio_phy = int(gpio_phy) - if gpio_phy < 0 raise "value_error", "invalid GPIO number" end - - import global - var rmt - # if "_rmt" is not initialized, set to an array of GPIO of size MAX_RMT - if !global.contains("_rmt") - rmt = [] - global._rmt = rmt - for i:0..gpio.MAX_RMT-1 - rmt.push(-1) - end - # if default WS2812 is set, assign RMT0 - if gpio.pin_used(gpio.WS2812, 0) - rmt[0] = gpio.pin(gpio.WS2812, 0) - end - end - - rmt = global._rmt - # find an already assigned slot or try to assign a new one - var i = 0 - var first_free = -1 - while i < gpio.MAX_RMT - var elt = rmt[i] - if elt == gpio_phy return i end # already assigned - if elt < 0 && first_free < 0 first_free = i end # found a free slot - i += 1 - end - if first_free >= 0 - rmt[first_free] = gpio_phy - return first_free - end - # no more slot - raise "internal_error", "no more RMT channel available" - end - def clear() self.clear_to(0x000000) self.show() @@ -109,17 +71,14 @@ class Leds : Leds_ntv return self.bri end - def ctor(leds, gpio_phy, typ, rmt) + def ctor(leds, gpio_phy, typ, hardware) if gpio_phy == nil self.call_native(0) # native driver else if typ == nil typ = self.WS2812_GRB end - if rmt == nil - rmt = self.assign_rmt(gpio_phy) - end - self.call_native(0, leds, gpio_phy, typ, rmt) + self.call_native(0, leds, gpio_phy, typ, hardware) end end def begin() @@ -155,9 +114,13 @@ class Leds : Leds_ntv def pixel_offset() return 0 end - def clear_to(col, bri) + def clear_to(col, bri, index, len) if (bri == nil) bri = self.bri end - self.call_native(9, self.to_gamma(col, bri)) + if index != nil && len != nil + self.call_native(9, self.to_gamma(col, bri), index, len) + else + self.call_native(9, self.to_gamma(col, bri)) + end end def set_pixel_color(idx, col, bri) if (bri == nil) bri = self.bri end @@ -403,15 +366,15 @@ anim() #- -var s = Leds_matrix(5, 5, gpio.pin(gpio.WS2812, 1)) +var s = Leds(25, gpio.pin(gpio.WS2812, 1)).create_matrix(5, 5) s.set_alternate(true) -s.clear_to(0x300000) +s.clear_to(0x400000) s.show() x = 0 y = 0 def anim() - s.clear_to(0x300000) + s.clear_to(0x400000) s.set_matrix_pixel_color(x, y, 0x004000) s.show() y = (y + 1) % 5 diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h index 683e7e756..5a493db0e 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h @@ -3,471 +3,9 @@ * Generated code, don't edit * \********************************************************************/ #include "be_constobj.h" -extern const bclass be_class_Leds_segment; extern const bclass be_class_Leds; extern const bclass be_class_Leds_matrix; -// compact class 'Leds_segment' ktab size: 16, total: 34 (saved 144 bytes) -static const bvalue be_ktab_class_Leds_segment[16] = { - /* K0 */ be_nested_str(offset), - /* K1 */ be_nested_str(bri), - /* K2 */ be_nested_str(strip), - /* K3 */ be_nested_str(call_native), - /* K4 */ be_nested_str(to_gamma), - /* K5 */ be_nested_str(leds), - /* K6 */ be_nested_str(dirty), - /* K7 */ be_nested_str(can_show), - /* K8 */ be_nested_str(set_pixel_color), - /* K9 */ be_nested_str(is_dirty), - /* K10 */ be_nested_str(clear_to), - /* K11 */ be_const_int(0), - /* K12 */ be_nested_str(show), - /* K13 */ be_nested_str(get_pixel_color), - /* K14 */ be_nested_str(offseta), - /* K15 */ be_nested_str(pixel_size), -}; - - extern const bclass be_class_Leds_segment; - -/******************************************************************** -** Solidified function: pixel_offset -********************************************************************/ -be_local_closure(class_Leds_segment_pixel_offset, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_pixel_offset, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: clear_to -********************************************************************/ -be_local_closure(class_Leds_segment_clear_to, /* name */ - be_nested_proto( - 10, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_clear_to, - &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x4C0C0000, // 0000 LDNIL R3 - 0x1C0C0403, // 0001 EQ R3 R2 R3 - 0x780E0000, // 0002 JMPF R3 #0004 - 0x88080101, // 0003 GETMBR R2 R0 K1 - 0x880C0102, // 0004 GETMBR R3 R0 K2 - 0x8C0C0703, // 0005 GETMET R3 R3 K3 - 0x54160008, // 0006 LDINT R5 9 - 0x88180102, // 0007 GETMBR R6 R0 K2 - 0x8C180D04, // 0008 GETMET R6 R6 K4 - 0x5C200200, // 0009 MOVE R8 R1 - 0x5C240400, // 000A MOVE R9 R2 - 0x7C180600, // 000B CALL R6 3 - 0x881C0100, // 000C GETMBR R7 R0 K0 - 0x88200105, // 000D GETMBR R8 R0 K5 - 0x7C0C0A00, // 000E CALL R3 5 - 0x80000000, // 000F RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pixel_count -********************************************************************/ -be_local_closure(class_Leds_segment_pixel_count, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_pixel_count, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040105, // 0000 GETMBR R1 R0 K5 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pixels_buffer -********************************************************************/ -be_local_closure(class_Leds_segment_pixels_buffer, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_pixels_buffer, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x4C040000, // 0000 LDNIL R1 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: dirty -********************************************************************/ -be_local_closure(class_Leds_segment_dirty, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_dirty, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x8C040306, // 0001 GETMET R1 R1 K6 - 0x7C040200, // 0002 CALL R1 1 - 0x80000000, // 0003 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: can_show -********************************************************************/ -be_local_closure(class_Leds_segment_can_show, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_can_show, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x8C040307, // 0001 GETMET R1 R1 K7 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_pixel_color -********************************************************************/ -be_local_closure(class_Leds_segment_set_pixel_color, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_set_pixel_color, - &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x4C100000, // 0000 LDNIL R4 - 0x1C100604, // 0001 EQ R4 R3 R4 - 0x78120000, // 0002 JMPF R4 #0004 - 0x880C0101, // 0003 GETMBR R3 R0 K1 - 0x88100102, // 0004 GETMBR R4 R0 K2 - 0x8C100908, // 0005 GETMET R4 R4 K8 - 0x88180100, // 0006 GETMBR R6 R0 K0 - 0x00180206, // 0007 ADD R6 R1 R6 - 0x5C1C0400, // 0008 MOVE R7 R2 - 0x5C200600, // 0009 MOVE R8 R3 - 0x7C100800, // 000A CALL R4 4 - 0x80000000, // 000B RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: is_dirty -********************************************************************/ -be_local_closure(class_Leds_segment_is_dirty, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_is_dirty, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x8C040309, // 0001 GETMET R1 R1 K9 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: clear -********************************************************************/ -be_local_closure(class_Leds_segment_clear, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_clear, - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x8C04010A, // 0000 GETMET R1 R0 K10 - 0x580C000B, // 0001 LDCONST R3 K11 - 0x7C040400, // 0002 CALL R1 2 - 0x8C04010C, // 0003 GETMET R1 R0 K12 - 0x7C040200, // 0004 CALL R1 1 - 0x80000000, // 0005 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: begin -********************************************************************/ -be_local_closure(class_Leds_segment_begin, /* name */ - be_nested_proto( - 1, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_begin, - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_pixel_color -********************************************************************/ -be_local_closure(class_Leds_segment_get_pixel_color, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_get_pixel_color, - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x88080102, // 0000 GETMBR R2 R0 K2 - 0x8C08050D, // 0001 GETMET R2 R2 K13 - 0x8810010E, // 0002 GETMBR R4 R0 K14 - 0x00100204, // 0003 ADD R4 R1 R4 - 0x7C080400, // 0004 CALL R2 2 - 0x80040400, // 0005 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pixel_size -********************************************************************/ -be_local_closure(class_Leds_segment_pixel_size, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_pixel_size, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x8C04030F, // 0001 GETMET R1 R1 K15 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(class_Leds_segment_init, /* name */ - be_nested_proto( - 6, /* nstack */ - 4, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_init, - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x90020401, // 0000 SETMBR R0 K2 R1 - 0x60100009, // 0001 GETGBL R4 G9 - 0x5C140400, // 0002 MOVE R5 R2 - 0x7C100200, // 0003 CALL R4 1 - 0x90020004, // 0004 SETMBR R0 K0 R4 - 0x60100009, // 0005 GETGBL R4 G9 - 0x5C140600, // 0006 MOVE R5 R3 - 0x7C100200, // 0007 CALL R4 1 - 0x90020A04, // 0008 SETMBR R0 K5 R4 - 0x80000000, // 0009 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: show -********************************************************************/ -be_local_closure(class_Leds_segment_show, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_show, - &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x60080017, // 0000 GETGBL R2 G23 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x740A0007, // 0003 JMPT R2 #000C - 0x88080100, // 0004 GETMBR R2 R0 K0 - 0x1C08050B, // 0005 EQ R2 R2 K11 - 0x780A0007, // 0006 JMPF R2 #000F - 0x88080105, // 0007 GETMBR R2 R0 K5 - 0x880C0102, // 0008 GETMBR R3 R0 K2 - 0x880C0705, // 0009 GETMBR R3 R3 K5 - 0x1C080403, // 000A EQ R2 R2 R3 - 0x780A0002, // 000B JMPF R2 #000F - 0x88080102, // 000C GETMBR R2 R0 K2 - 0x8C08050C, // 000D GETMET R2 R2 K12 - 0x7C080200, // 000E CALL R2 1 - 0x80000000, // 000F RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Leds_segment -********************************************************************/ -be_local_class(Leds_segment, - 3, - NULL, - be_nested_map(17, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(pixel_offset, 9), be_const_closure(class_Leds_segment_pixel_offset_closure) }, - { be_const_key(clear_to, -1), be_const_closure(class_Leds_segment_clear_to_closure) }, - { be_const_key(show, -1), be_const_closure(class_Leds_segment_show_closure) }, - { be_const_key(pixels_buffer, 10), be_const_closure(class_Leds_segment_pixels_buffer_closure) }, - { be_const_key(offset, -1), be_const_var(1) }, - { be_const_key(dirty, -1), be_const_closure(class_Leds_segment_dirty_closure) }, - { be_const_key(can_show, -1), be_const_closure(class_Leds_segment_can_show_closure) }, - { be_const_key(set_pixel_color, 6), be_const_closure(class_Leds_segment_set_pixel_color_closure) }, - { be_const_key(get_pixel_color, -1), be_const_closure(class_Leds_segment_get_pixel_color_closure) }, - { be_const_key(pixel_count, -1), be_const_closure(class_Leds_segment_pixel_count_closure) }, - { be_const_key(strip, 7), be_const_var(0) }, - { be_const_key(leds, -1), be_const_var(2) }, - { be_const_key(begin, -1), be_const_closure(class_Leds_segment_begin_closure) }, - { be_const_key(is_dirty, 8), be_const_closure(class_Leds_segment_is_dirty_closure) }, - { be_const_key(pixel_size, -1), be_const_closure(class_Leds_segment_pixel_size_closure) }, - { be_const_key(init, -1), be_const_closure(class_Leds_segment_init_closure) }, - { be_const_key(clear, 2), be_const_closure(class_Leds_segment_clear_closure) }, - })), - (bstring*) &be_const_str_Leds_segment -); // compact class 'Leds_matrix' ktab size: 24, total: 62 (saved 304 bytes) static const bvalue be_ktab_class_Leds_matrix[24] = { /* K0 */ be_nested_str(strip), @@ -1111,140 +649,35 @@ be_local_class(Leds_matrix, })), (bstring*) &be_const_str_Leds_matrix ); -// compact class 'Leds' ktab size: 43, total: 83 (saved 320 bytes) -static const bvalue be_ktab_class_Leds[43] = { - /* K0 */ be_nested_str(leds), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str(value_error), - /* K3 */ be_nested_str(out_X20of_X20range), - /* K4 */ be_const_class(be_class_Leds_segment), - /* K5 */ be_nested_str(bri), - /* K6 */ be_nested_str(call_native), - /* K7 */ be_const_int(1), - /* K8 */ be_nested_str(clear_to), - /* K9 */ be_nested_str(show), - /* K10 */ be_nested_str(gpio), - /* K11 */ be_nested_str(gamma), - /* K12 */ be_nested_str(pin), - /* K13 */ be_nested_str(WS2812), - /* K14 */ be_nested_str(ctor), - /* K15 */ be_nested_str(pixel_count), - /* K16 */ be_nested_str(light), - /* K17 */ be_nested_str(get), - /* K18 */ be_nested_str(_p), - /* K19 */ be_nested_str(internal_error), - /* K20 */ be_nested_str(couldn_X27t_X20not_X20initialize_X20noepixelbus), - /* K21 */ be_nested_str(begin), - /* K22 */ be_nested_str(apply_bri_gamma), - /* K23 */ be_const_int(2), - /* K24 */ be_const_class(be_class_Leds), - /* K25 */ be_nested_str(Leds), - /* K26 */ be_nested_str(create_matrix), - /* K27 */ be_nested_str(to_gamma), - /* K28 */ be_const_class(be_class_Leds_matrix), - /* K29 */ be_const_int(3), - /* K30 */ be_nested_str(invalid_X20GPIO_X20number), - /* K31 */ be_nested_str(global), - /* K32 */ be_nested_str(contains), - /* K33 */ be_nested_str(_rmt), - /* K34 */ be_nested_str(MAX_RMT), - /* K35 */ be_nested_str(push), - /* K36 */ be_nested_str(stop_iteration), - /* K37 */ be_nested_str(pin_used), - /* K38 */ be_nested_str(no_X20more_X20RMT_X20channel_X20available), - /* K39 */ be_nested_str(WS2812_GRB), - /* K40 */ be_nested_str(assign_rmt), - /* K41 */ be_nested_str(pixel_size), - /* K42 */ be_nested_str(_change_buffer), +// compact class 'Leds_segment' ktab size: 16, total: 34 (saved 144 bytes) +static const bvalue be_ktab_class_Leds_segment[16] = { + /* K0 */ be_nested_str(offset), + /* K1 */ be_nested_str(bri), + /* K2 */ be_nested_str(strip), + /* K3 */ be_nested_str(call_native), + /* K4 */ be_nested_str(to_gamma), + /* K5 */ be_nested_str(leds), + /* K6 */ be_nested_str(dirty), + /* K7 */ be_nested_str(can_show), + /* K8 */ be_nested_str(set_pixel_color), + /* K9 */ be_nested_str(is_dirty), + /* K10 */ be_nested_str(clear_to), + /* K11 */ be_const_int(0), + /* K12 */ be_nested_str(show), + /* K13 */ be_nested_str(get_pixel_color), + /* K14 */ be_nested_str(offseta), + /* K15 */ be_nested_str(pixel_size), }; -extern const bclass be_class_Leds; +extern const bclass be_class_Leds_segment; /******************************************************************** -** Solidified function: create_segment +** Solidified function: pixel_offset ********************************************************************/ -be_local_closure(class_Leds_create_segment, /* name */ +be_local_closure(class_Leds_segment_pixel_offset, /* name */ be_nested_proto( - 8, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_create_segment, - &be_const_str_solidified, - ( &(const binstruction[23]) { /* code */ - 0x600C0009, // 0000 GETGBL R3 G9 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C0C0200, // 0002 CALL R3 1 - 0x60100009, // 0003 GETGBL R4 G9 - 0x5C140400, // 0004 MOVE R5 R2 - 0x7C100200, // 0005 CALL R4 1 - 0x000C0604, // 0006 ADD R3 R3 R4 - 0x88100100, // 0007 GETMBR R4 R0 K0 - 0x240C0604, // 0008 GT R3 R3 R4 - 0x740E0003, // 0009 JMPT R3 #000E - 0x140C0301, // 000A LT R3 R1 K1 - 0x740E0001, // 000B JMPT R3 #000E - 0x140C0501, // 000C LT R3 R2 K1 - 0x780E0000, // 000D JMPF R3 #000F - 0xB0060503, // 000E RAISE 1 K2 K3 - 0x580C0004, // 000F LDCONST R3 K4 - 0xB4000004, // 0010 CLASS K4 - 0x5C100600, // 0011 MOVE R4 R3 - 0x5C140000, // 0012 MOVE R5 R0 - 0x5C180200, // 0013 MOVE R6 R1 - 0x5C1C0400, // 0014 MOVE R7 R2 - 0x7C100600, // 0015 CALL R4 3 - 0x80040800, // 0016 RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_bri -********************************************************************/ -be_local_closure(class_Leds_set_bri, /* name */ - be_nested_proto( - 3, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_set_bri, - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x14080301, // 0000 LT R2 R1 K1 - 0x780A0000, // 0001 JMPF R2 #0003 - 0x58040001, // 0002 LDCONST R1 K1 - 0x540A00FE, // 0003 LDINT R2 255 - 0x24080202, // 0004 GT R2 R1 R2 - 0x780A0000, // 0005 JMPF R2 #0007 - 0x540600FE, // 0006 LDINT R1 255 - 0x90020A01, // 0007 SETMBR R0 K5 R1 - 0x80000000, // 0008 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: begin -********************************************************************/ -be_local_closure(class_Leds_begin, /* name */ - be_nested_proto( - 4, /* nstack */ + 2, /* nstack */ 1, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -1252,14 +685,12 @@ be_local_closure(class_Leds_begin, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_begin, + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_pixel_offset, &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040106, // 0000 GETMET R1 R0 K6 - 0x580C0007, // 0001 LDCONST R3 K7 - 0x7C040400, // 0002 CALL R1 2 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -1267,106 +698,11 @@ be_local_closure(class_Leds_begin, /* name */ /******************************************************************** -** Solidified function: clear +** Solidified function: clear_to ********************************************************************/ -be_local_closure(class_Leds_clear, /* name */ +be_local_closure(class_Leds_segment_clear_to, /* name */ be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_clear, - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x8C040108, // 0000 GETMET R1 R0 K8 - 0x580C0001, // 0001 LDCONST R3 K1 - 0x7C040400, // 0002 CALL R1 2 - 0x8C040109, // 0003 GETMET R1 R0 K9 - 0x7C040200, // 0004 CALL R1 1 - 0x80000000, // 0005 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(class_Leds_init, /* name */ - be_nested_proto( - 12, /* nstack */ - 5, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_init, - &be_const_str_solidified, - ( &(const binstruction[43]) { /* code */ - 0xA4161400, // 0000 IMPORT R5 K10 - 0x50180200, // 0001 LDBOOL R6 1 0 - 0x90021606, // 0002 SETMBR R0 K11 R6 - 0x4C180000, // 0003 LDNIL R6 - 0x1C180406, // 0004 EQ R6 R2 R6 - 0x741A0005, // 0005 JMPT R6 #000C - 0x8C180B0C, // 0006 GETMET R6 R5 K12 - 0x88200B0D, // 0007 GETMBR R8 R5 K13 - 0x58240001, // 0008 LDCONST R9 K1 - 0x7C180600, // 0009 CALL R6 3 - 0x1C180406, // 000A EQ R6 R2 R6 - 0x781A000A, // 000B JMPF R6 #0017 - 0x8C18010E, // 000C GETMET R6 R0 K14 - 0x7C180200, // 000D CALL R6 1 - 0x8C18010F, // 000E GETMET R6 R0 K15 - 0x7C180200, // 000F CALL R6 1 - 0x90020006, // 0010 SETMBR R0 K0 R6 - 0xA41A2000, // 0011 IMPORT R6 K16 - 0x8C1C0D11, // 0012 GETMET R7 R6 K17 - 0x7C1C0200, // 0013 CALL R7 1 - 0x941C0F05, // 0014 GETIDX R7 R7 K5 - 0x90020A07, // 0015 SETMBR R0 K5 R7 - 0x7002000B, // 0016 JMP #0023 - 0x60180009, // 0017 GETGBL R6 G9 - 0x5C1C0200, // 0018 MOVE R7 R1 - 0x7C180200, // 0019 CALL R6 1 - 0x90020006, // 001A SETMBR R0 K0 R6 - 0x541A007E, // 001B LDINT R6 127 - 0x90020A06, // 001C SETMBR R0 K5 R6 - 0x8C18010E, // 001D GETMET R6 R0 K14 - 0x88200100, // 001E GETMBR R8 R0 K0 - 0x5C240400, // 001F MOVE R9 R2 - 0x5C280600, // 0020 MOVE R10 R3 - 0x5C2C0800, // 0021 MOVE R11 R4 - 0x7C180A00, // 0022 CALL R6 5 - 0x88180112, // 0023 GETMBR R6 R0 K18 - 0x4C1C0000, // 0024 LDNIL R7 - 0x1C180C07, // 0025 EQ R6 R6 R7 - 0x781A0000, // 0026 JMPF R6 #0028 - 0xB0062714, // 0027 RAISE 1 K19 K20 - 0x8C180115, // 0028 GETMET R6 R0 K21 - 0x7C180200, // 0029 CALL R6 1 - 0x80000000, // 002A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: to_gamma -********************************************************************/ -be_local_closure(class_Leds_to_gamma, /* name */ - be_nested_proto( - 8, /* nstack */ + 10, /* nstack */ 3, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -1374,47 +710,26 @@ be_local_closure(class_Leds_to_gamma, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_to_gamma, + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_clear_to, &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ + ( &(const binstruction[16]) { /* code */ 0x4C0C0000, // 0000 LDNIL R3 0x1C0C0403, // 0001 EQ R3 R2 R3 0x780E0000, // 0002 JMPF R3 #0004 - 0x88080105, // 0003 GETMBR R2 R0 K5 - 0x8C0C0116, // 0004 GETMET R3 R0 K22 - 0x5C140200, // 0005 MOVE R5 R1 - 0x5C180400, // 0006 MOVE R6 R2 - 0x881C010B, // 0007 GETMBR R7 R0 K11 - 0x7C0C0800, // 0008 CALL R3 4 - 0x80040600, // 0009 RET 1 R3 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: show -********************************************************************/ -be_local_closure(class_Leds_show, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_show, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040106, // 0000 GETMET R1 R0 K6 - 0x580C0017, // 0001 LDCONST R3 K23 - 0x7C040400, // 0002 CALL R1 2 - 0x80000000, // 0003 RET 0 + 0x88080101, // 0003 GETMBR R2 R0 K1 + 0x880C0102, // 0004 GETMBR R3 R0 K2 + 0x8C0C0703, // 0005 GETMET R3 R3 K3 + 0x54160008, // 0006 LDINT R5 9 + 0x88180102, // 0007 GETMBR R6 R0 K2 + 0x8C180D04, // 0008 GETMET R6 R6 K4 + 0x5C200200, // 0009 MOVE R8 R1 + 0x5C240400, // 000A MOVE R9 R2 + 0x7C180600, // 000B CALL R6 3 + 0x881C0100, // 000C GETMBR R7 R0 K0 + 0x88200105, // 000D GETMBR R8 R0 K5 + 0x7C0C0A00, // 000E CALL R3 5 + 0x80000000, // 000F RET 0 }) ) ); @@ -1424,7 +739,422 @@ be_local_closure(class_Leds_show, /* name */ /******************************************************************** ** Solidified function: pixel_count ********************************************************************/ -be_local_closure(class_Leds_pixel_count, /* name */ +be_local_closure(class_Leds_segment_pixel_count, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_pixel_count, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040105, // 0000 GETMBR R1 R0 K5 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pixels_buffer +********************************************************************/ +be_local_closure(class_Leds_segment_pixels_buffer, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_pixels_buffer, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x4C040000, // 0000 LDNIL R1 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: dirty +********************************************************************/ +be_local_closure(class_Leds_segment_dirty, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_dirty, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C040306, // 0001 GETMET R1 R1 K6 + 0x7C040200, // 0002 CALL R1 1 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: can_show +********************************************************************/ +be_local_closure(class_Leds_segment_can_show, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_can_show, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C040307, // 0001 GETMET R1 R1 K7 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_pixel_color +********************************************************************/ +be_local_closure(class_Leds_segment_set_pixel_color, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_set_pixel_color, + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x1C100604, // 0001 EQ R4 R3 R4 + 0x78120000, // 0002 JMPF R4 #0004 + 0x880C0101, // 0003 GETMBR R3 R0 K1 + 0x88100102, // 0004 GETMBR R4 R0 K2 + 0x8C100908, // 0005 GETMET R4 R4 K8 + 0x88180100, // 0006 GETMBR R6 R0 K0 + 0x00180206, // 0007 ADD R6 R1 R6 + 0x5C1C0400, // 0008 MOVE R7 R2 + 0x5C200600, // 0009 MOVE R8 R3 + 0x7C100800, // 000A CALL R4 4 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: is_dirty +********************************************************************/ +be_local_closure(class_Leds_segment_is_dirty, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_is_dirty, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C040309, // 0001 GETMET R1 R1 K9 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: clear +********************************************************************/ +be_local_closure(class_Leds_segment_clear, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_clear, + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x8C04010A, // 0000 GETMET R1 R0 K10 + 0x580C000B, // 0001 LDCONST R3 K11 + 0x7C040400, // 0002 CALL R1 2 + 0x8C04010C, // 0003 GETMET R1 R0 K12 + 0x7C040200, // 0004 CALL R1 1 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: begin +********************************************************************/ +be_local_closure(class_Leds_segment_begin, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_begin, + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_pixel_color +********************************************************************/ +be_local_closure(class_Leds_segment_get_pixel_color, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_get_pixel_color, + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88080102, // 0000 GETMBR R2 R0 K2 + 0x8C08050D, // 0001 GETMET R2 R2 K13 + 0x8810010E, // 0002 GETMBR R4 R0 K14 + 0x00100204, // 0003 ADD R4 R1 R4 + 0x7C080400, // 0004 CALL R2 2 + 0x80040400, // 0005 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pixel_size +********************************************************************/ +be_local_closure(class_Leds_segment_pixel_size, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_pixel_size, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C04030F, // 0001 GETMET R1 R1 K15 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(class_Leds_segment_init, /* name */ + be_nested_proto( + 6, /* nstack */ + 4, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_init, + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x90020401, // 0000 SETMBR R0 K2 R1 + 0x60100009, // 0001 GETGBL R4 G9 + 0x5C140400, // 0002 MOVE R5 R2 + 0x7C100200, // 0003 CALL R4 1 + 0x90020004, // 0004 SETMBR R0 K0 R4 + 0x60100009, // 0005 GETGBL R4 G9 + 0x5C140600, // 0006 MOVE R5 R3 + 0x7C100200, // 0007 CALL R4 1 + 0x90020A04, // 0008 SETMBR R0 K5 R4 + 0x80000000, // 0009 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: show +********************************************************************/ +be_local_closure(class_Leds_segment_show, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_show, + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0x60080017, // 0000 GETGBL R2 G23 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x740A0007, // 0003 JMPT R2 #000C + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x1C08050B, // 0005 EQ R2 R2 K11 + 0x780A0007, // 0006 JMPF R2 #000F + 0x88080105, // 0007 GETMBR R2 R0 K5 + 0x880C0102, // 0008 GETMBR R3 R0 K2 + 0x880C0705, // 0009 GETMBR R3 R3 K5 + 0x1C080403, // 000A EQ R2 R2 R3 + 0x780A0002, // 000B JMPF R2 #000F + 0x88080102, // 000C GETMBR R2 R0 K2 + 0x8C08050C, // 000D GETMET R2 R2 K12 + 0x7C080200, // 000E CALL R2 1 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Leds_segment +********************************************************************/ +be_local_class(Leds_segment, + 3, + NULL, + be_nested_map(17, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key(pixel_offset, 9), be_const_closure(class_Leds_segment_pixel_offset_closure) }, + { be_const_key(clear_to, -1), be_const_closure(class_Leds_segment_clear_to_closure) }, + { be_const_key(show, -1), be_const_closure(class_Leds_segment_show_closure) }, + { be_const_key(pixels_buffer, 10), be_const_closure(class_Leds_segment_pixels_buffer_closure) }, + { be_const_key(offset, -1), be_const_var(1) }, + { be_const_key(dirty, -1), be_const_closure(class_Leds_segment_dirty_closure) }, + { be_const_key(can_show, -1), be_const_closure(class_Leds_segment_can_show_closure) }, + { be_const_key(set_pixel_color, 6), be_const_closure(class_Leds_segment_set_pixel_color_closure) }, + { be_const_key(get_pixel_color, -1), be_const_closure(class_Leds_segment_get_pixel_color_closure) }, + { be_const_key(pixel_count, -1), be_const_closure(class_Leds_segment_pixel_count_closure) }, + { be_const_key(strip, 7), be_const_var(0) }, + { be_const_key(leds, -1), be_const_var(2) }, + { be_const_key(begin, -1), be_const_closure(class_Leds_segment_begin_closure) }, + { be_const_key(is_dirty, 8), be_const_closure(class_Leds_segment_is_dirty_closure) }, + { be_const_key(pixel_size, -1), be_const_closure(class_Leds_segment_pixel_size_closure) }, + { be_const_key(init, -1), be_const_closure(class_Leds_segment_init_closure) }, + { be_const_key(clear, 2), be_const_closure(class_Leds_segment_clear_closure) }, + })), + (bstring*) &be_const_str_Leds_segment +); +// compact class 'Leds' ktab size: 33, total: 65 (saved 256 bytes) +static const bvalue be_ktab_class_Leds[33] = { + /* K0 */ be_nested_str(call_native), + /* K1 */ be_nested_str(bri), + /* K2 */ be_const_class(be_class_Leds), + /* K3 */ be_nested_str(Leds), + /* K4 */ be_nested_str(create_matrix), + /* K5 */ be_const_int(0), + /* K6 */ be_const_int(3), + /* K7 */ be_nested_str(gamma), + /* K8 */ be_const_int(2), + /* K9 */ be_nested_str(WS2812_GRB), + /* K10 */ be_nested_str(leds), + /* K11 */ be_nested_str(value_error), + /* K12 */ be_nested_str(out_X20of_X20range), + /* K13 */ be_const_class(be_class_Leds_matrix), + /* K14 */ be_nested_str(to_gamma), + /* K15 */ be_const_class(be_class_Leds_segment), + /* K16 */ be_nested_str(gpio), + /* K17 */ be_nested_str(pin), + /* K18 */ be_nested_str(WS2812), + /* K19 */ be_nested_str(ctor), + /* K20 */ be_nested_str(pixel_count), + /* K21 */ be_nested_str(light), + /* K22 */ be_nested_str(get), + /* K23 */ be_nested_str(_p), + /* K24 */ be_nested_str(internal_error), + /* K25 */ be_nested_str(couldn_X27t_X20not_X20initialize_X20noepixelbus), + /* K26 */ be_nested_str(begin), + /* K27 */ be_nested_str(clear_to), + /* K28 */ be_nested_str(show), + /* K29 */ be_const_int(1), + /* K30 */ be_nested_str(apply_bri_gamma), + /* K31 */ be_nested_str(pixel_size), + /* K32 */ be_nested_str(_change_buffer), +}; + + +extern const bclass be_class_Leds; + +/******************************************************************** +** Solidified function: is_dirty +********************************************************************/ +be_local_closure(class_Leds_is_dirty, /* name */ be_nested_proto( 4, /* nstack */ 1, /* argc */ @@ -1435,11 +1165,11 @@ be_local_closure(class_Leds_pixel_count, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_pixel_count, + &be_const_str_is_dirty, &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C040106, // 0000 GETMET R1 R0 K6 - 0x540E0007, // 0001 LDINT R3 8 + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0003, // 0001 LDINT R3 4 0x7C040400, // 0002 CALL R1 2 0x80040200, // 0003 RET 1 R1 }) @@ -1465,7 +1195,7 @@ be_local_closure(class_Leds_get_bri, /* name */ &be_const_str_get_bri, &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ - 0x88040105, // 0000 GETMBR R1 R0 K5 + 0x88040101, // 0000 GETMBR R1 R0 K1 0x80040200, // 0001 RET 1 R1 }) ) @@ -1473,6 +1203,100 @@ be_local_closure(class_Leds_get_bri, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: matrix +********************************************************************/ +be_local_closure(class_Leds_matrix, /* name */ + be_nested_proto( + 11, /* nstack */ + 4, /* argc */ + 12, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_matrix, + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x58100002, // 0000 LDCONST R4 K2 + 0xB8160600, // 0001 GETNGBL R5 K3 + 0x08180001, // 0002 MUL R6 R0 R1 + 0x5C1C0400, // 0003 MOVE R7 R2 + 0x5C200600, // 0004 MOVE R8 R3 + 0x7C140600, // 0005 CALL R5 3 + 0x8C180B04, // 0006 GETMET R6 R5 K4 + 0x5C200000, // 0007 MOVE R8 R0 + 0x5C240200, // 0008 MOVE R9 R1 + 0x58280005, // 0009 LDCONST R10 K5 + 0x7C180800, // 000A CALL R6 4 + 0x80040C00, // 000B RET 1 R6 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: can_show +********************************************************************/ +be_local_closure(class_Leds_can_show, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_can_show, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x580C0006, // 0001 LDCONST R3 K6 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_bri +********************************************************************/ +be_local_closure(class_Leds_set_bri, /* name */ + be_nested_proto( + 3, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_set_bri, + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x14080305, // 0000 LT R2 R1 K5 + 0x780A0000, // 0001 JMPF R2 #0003 + 0x58040005, // 0002 LDCONST R1 K5 + 0x540A00FE, // 0003 LDINT R2 255 + 0x24080202, // 0004 GT R2 R1 R2 + 0x780A0000, // 0005 JMPF R2 #0007 + 0x540600FE, // 0006 LDINT R1 255 + 0x90020201, // 0007 SETMBR R0 K1 R1 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: set_gamma ********************************************************************/ @@ -1493,7 +1317,7 @@ be_local_closure(class_Leds_set_gamma, /* name */ 0x60080017, // 0000 GETGBL R2 G23 0x5C0C0200, // 0001 MOVE R3 R1 0x7C080200, // 0002 CALL R2 1 - 0x90021602, // 0003 SETMBR R0 K11 R2 + 0x90020E02, // 0003 SETMBR R0 K7 R2 0x80000000, // 0004 RET 0 }) ) @@ -1502,37 +1326,9 @@ be_local_closure(class_Leds_set_gamma, /* name */ /******************************************************************** -** Solidified function: get_pixel_color +** Solidified function: show ********************************************************************/ -be_local_closure(class_Leds_get_pixel_color, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_get_pixel_color, - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x8C080106, // 0000 GETMET R2 R0 K6 - 0x5412000A, // 0001 LDINT R4 11 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C080600, // 0003 CALL R2 3 - 0x80040400, // 0004 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: dirty -********************************************************************/ -be_local_closure(class_Leds_dirty, /* name */ +be_local_closure(class_Leds_show, /* name */ be_nested_proto( 4, /* nstack */ 1, /* argc */ @@ -1543,11 +1339,11 @@ be_local_closure(class_Leds_dirty, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_dirty, + &be_const_str_show, &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C040106, // 0000 GETMET R1 R0 K6 - 0x540E0004, // 0001 LDINT R3 5 + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x580C0008, // 0001 LDCONST R3 K8 0x7C040400, // 0002 CALL R1 2 0x80000000, // 0003 RET 0 }) @@ -1557,106 +1353,12 @@ be_local_closure(class_Leds_dirty, /* name */ /******************************************************************** -** Solidified function: matrix +** Solidified function: ctor ********************************************************************/ -be_local_closure(class_Leds_matrix, /* name */ - be_nested_proto( - 11, /* nstack */ - 4, /* argc */ - 12, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_matrix, - &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x58100018, // 0000 LDCONST R4 K24 - 0xB8163200, // 0001 GETNGBL R5 K25 - 0x08180001, // 0002 MUL R6 R0 R1 - 0x5C1C0400, // 0003 MOVE R7 R2 - 0x5C200600, // 0004 MOVE R8 R3 - 0x7C140600, // 0005 CALL R5 3 - 0x8C180B1A, // 0006 GETMET R6 R5 K26 - 0x5C200000, // 0007 MOVE R8 R0 - 0x5C240200, // 0008 MOVE R9 R1 - 0x58280001, // 0009 LDCONST R10 K1 - 0x7C180800, // 000A CALL R6 4 - 0x80040C00, // 000B RET 1 R6 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pixel_offset -********************************************************************/ -be_local_closure(class_Leds_pixel_offset, /* name */ - be_nested_proto( - 1, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_pixel_offset, - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80060200, // 0000 RET 1 K1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: clear_to -********************************************************************/ -be_local_closure(class_Leds_clear_to, /* name */ - be_nested_proto( - 10, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_clear_to, - &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x4C0C0000, // 0000 LDNIL R3 - 0x1C0C0403, // 0001 EQ R3 R2 R3 - 0x780E0000, // 0002 JMPF R3 #0004 - 0x88080105, // 0003 GETMBR R2 R0 K5 - 0x8C0C0106, // 0004 GETMET R3 R0 K6 - 0x54160008, // 0005 LDINT R5 9 - 0x8C18011B, // 0006 GETMET R6 R0 K27 - 0x5C200200, // 0007 MOVE R8 R1 - 0x5C240400, // 0008 MOVE R9 R2 - 0x7C180600, // 0009 CALL R6 3 - 0x7C0C0600, // 000A CALL R3 3 - 0x80000000, // 000B RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_pixel_color -********************************************************************/ -be_local_closure(class_Leds_set_pixel_color, /* name */ +be_local_closure(class_Leds_ctor, /* name */ be_nested_proto( 12, /* nstack */ - 4, /* argc */ + 5, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -1664,22 +1366,28 @@ be_local_closure(class_Leds_set_pixel_color, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_set_pixel_color, + &be_const_str_ctor, &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x4C100000, // 0000 LDNIL R4 - 0x1C100604, // 0001 EQ R4 R3 R4 - 0x78120000, // 0002 JMPF R4 #0004 - 0x880C0105, // 0003 GETMBR R3 R0 K5 - 0x8C100106, // 0004 GETMET R4 R0 K6 - 0x541A0009, // 0005 LDINT R6 10 - 0x5C1C0200, // 0006 MOVE R7 R1 - 0x8C20011B, // 0007 GETMET R8 R0 K27 - 0x5C280400, // 0008 MOVE R10 R2 - 0x5C2C0600, // 0009 MOVE R11 R3 - 0x7C200600, // 000A CALL R8 3 - 0x7C100800, // 000B CALL R4 4 - 0x80000000, // 000C RET 0 + ( &(const binstruction[19]) { /* code */ + 0x4C140000, // 0000 LDNIL R5 + 0x1C140405, // 0001 EQ R5 R2 R5 + 0x78160003, // 0002 JMPF R5 #0007 + 0x8C140100, // 0003 GETMET R5 R0 K0 + 0x581C0005, // 0004 LDCONST R7 K5 + 0x7C140400, // 0005 CALL R5 2 + 0x7002000A, // 0006 JMP #0012 + 0x4C140000, // 0007 LDNIL R5 + 0x1C140605, // 0008 EQ R5 R3 R5 + 0x78160000, // 0009 JMPF R5 #000B + 0x880C0109, // 000A GETMBR R3 R0 K9 + 0x8C140100, // 000B GETMET R5 R0 K0 + 0x581C0005, // 000C LDCONST R7 K5 + 0x5C200200, // 000D MOVE R8 R1 + 0x5C240400, // 000E MOVE R9 R2 + 0x5C280600, // 000F MOVE R10 R3 + 0x5C2C0800, // 0010 MOVE R11 R4 + 0x7C140C00, // 0011 CALL R5 6 + 0x80000000, // 0012 RET 0 }) ) ); @@ -1703,7 +1411,7 @@ be_local_closure(class_Leds_pixel_size, /* name */ &be_const_str_pixel_size, &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C040106, // 0000 GETMET R1 R0 K6 + 0x8C040100, // 0000 GETMET R1 R0 K0 0x540E0006, // 0001 LDINT R3 7 0x7C040400, // 0002 CALL R1 2 0x80040200, // 0003 RET 1 R1 @@ -1713,6 +1421,110 @@ be_local_closure(class_Leds_pixel_size, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: dirty +********************************************************************/ +be_local_closure(class_Leds_dirty, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_dirty, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0004, // 0001 LDINT R3 5 + 0x7C040400, // 0002 CALL R1 2 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pixel_offset +********************************************************************/ +be_local_closure(class_Leds_pixel_offset, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_pixel_offset, + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80060A00, // 0000 RET 1 K5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_pixel_color +********************************************************************/ +be_local_closure(class_Leds_get_pixel_color, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_get_pixel_color, + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5412000A, // 0001 LDINT R4 11 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C080600, // 0003 CALL R2 3 + 0x80040400, // 0004 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_gamma +********************************************************************/ +be_local_closure(class_Leds_get_gamma, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_get_gamma, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040107, // 0000 GETMBR R1 R0 K7 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: create_matrix ********************************************************************/ @@ -1745,21 +1557,21 @@ be_local_closure(class_Leds_create_matrix, /* name */ 0x4C100000, // 000C LDNIL R4 0x1C100604, // 000D EQ R4 R3 R4 0x78120000, // 000E JMPF R4 #0010 - 0x580C0001, // 000F LDCONST R3 K1 + 0x580C0005, // 000F LDCONST R3 K5 0x08100202, // 0010 MUL R4 R1 R2 0x00100803, // 0011 ADD R4 R4 R3 - 0x88140100, // 0012 GETMBR R5 R0 K0 + 0x8814010A, // 0012 GETMBR R5 R0 K10 0x24100805, // 0013 GT R4 R4 R5 0x74120005, // 0014 JMPT R4 #001B - 0x14100501, // 0015 LT R4 R2 K1 + 0x14100505, // 0015 LT R4 R2 K5 0x74120003, // 0016 JMPT R4 #001B - 0x14100301, // 0017 LT R4 R1 K1 + 0x14100305, // 0017 LT R4 R1 K5 0x74120001, // 0018 JMPT R4 #001B - 0x14100701, // 0019 LT R4 R3 K1 + 0x14100705, // 0019 LT R4 R3 K5 0x78120000, // 001A JMPF R4 #001C - 0xB0060503, // 001B RAISE 1 K2 K3 - 0x5810001C, // 001C LDCONST R4 K28 - 0xB400001C, // 001D CLASS K28 + 0xB006170C, // 001B RAISE 1 K11 K12 + 0x5810000D, // 001C LDCONST R4 K13 + 0xB400000D, // 001D CLASS K13 0x5C140800, // 001E MOVE R5 R4 0x5C180000, // 001F MOVE R6 R0 0x5C1C0200, // 0020 MOVE R7 R1 @@ -1774,183 +1586,9 @@ be_local_closure(class_Leds_create_matrix, /* name */ /******************************************************************** -** Solidified function: get_gamma +** Solidified function: clear_to ********************************************************************/ -be_local_closure(class_Leds_get_gamma, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_get_gamma, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x8804010B, // 0000 GETMBR R1 R0 K11 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: is_dirty -********************************************************************/ -be_local_closure(class_Leds_is_dirty, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_is_dirty, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040106, // 0000 GETMET R1 R0 K6 - 0x540E0003, // 0001 LDINT R3 4 - 0x7C040400, // 0002 CALL R1 2 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: can_show -********************************************************************/ -be_local_closure(class_Leds_can_show, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_can_show, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040106, // 0000 GETMET R1 R0 K6 - 0x580C001D, // 0001 LDCONST R3 K29 - 0x7C040400, // 0002 CALL R1 2 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: assign_rmt -********************************************************************/ -be_local_closure(class_Leds_assign_rmt, /* name */ - be_nested_proto( - 9, /* nstack */ - 1, /* argc */ - 12, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_assign_rmt, - &be_const_str_solidified, - ( &(const binstruction[72]) { /* code */ - 0x58040018, // 0000 LDCONST R1 K24 - 0x60080009, // 0001 GETGBL R2 G9 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C080200, // 0003 CALL R2 1 - 0x5C000400, // 0004 MOVE R0 R2 - 0x14080101, // 0005 LT R2 R0 K1 - 0x780A0000, // 0006 JMPF R2 #0008 - 0xB006051E, // 0007 RAISE 1 K2 K30 - 0xA40A3E00, // 0008 IMPORT R2 K31 - 0x4C0C0000, // 0009 LDNIL R3 - 0x8C100520, // 000A GETMET R4 R2 K32 - 0x58180021, // 000B LDCONST R6 K33 - 0x7C100400, // 000C CALL R4 2 - 0x74120021, // 000D JMPT R4 #0030 - 0x60100012, // 000E GETGBL R4 G18 - 0x7C100000, // 000F CALL R4 0 - 0x5C0C0800, // 0010 MOVE R3 R4 - 0x900A4203, // 0011 SETMBR R2 K33 R3 - 0x60100010, // 0012 GETGBL R4 G16 - 0xB8161400, // 0013 GETNGBL R5 K10 - 0x88140B22, // 0014 GETMBR R5 R5 K34 - 0x04140B07, // 0015 SUB R5 R5 K7 - 0x40160205, // 0016 CONNECT R5 K1 R5 - 0x7C100200, // 0017 CALL R4 1 - 0xA8020005, // 0018 EXBLK 0 #001F - 0x5C140800, // 0019 MOVE R5 R4 - 0x7C140000, // 001A CALL R5 0 - 0x8C180723, // 001B GETMET R6 R3 K35 - 0x5421FFFE, // 001C LDINT R8 -1 - 0x7C180400, // 001D CALL R6 2 - 0x7001FFF9, // 001E JMP #0019 - 0x58100024, // 001F LDCONST R4 K36 - 0xAC100200, // 0020 CATCH R4 1 0 - 0xB0080000, // 0021 RAISE 2 R0 R0 - 0xB8121400, // 0022 GETNGBL R4 K10 - 0x8C100925, // 0023 GETMET R4 R4 K37 - 0xB81A1400, // 0024 GETNGBL R6 K10 - 0x88180D0D, // 0025 GETMBR R6 R6 K13 - 0x581C0001, // 0026 LDCONST R7 K1 - 0x7C100600, // 0027 CALL R4 3 - 0x78120006, // 0028 JMPF R4 #0030 - 0xB8121400, // 0029 GETNGBL R4 K10 - 0x8C10090C, // 002A GETMET R4 R4 K12 - 0xB81A1400, // 002B GETNGBL R6 K10 - 0x88180D0D, // 002C GETMBR R6 R6 K13 - 0x581C0001, // 002D LDCONST R7 K1 - 0x7C100600, // 002E CALL R4 3 - 0x980E0204, // 002F SETIDX R3 K1 R4 - 0x880C0521, // 0030 GETMBR R3 R2 K33 - 0x58100001, // 0031 LDCONST R4 K1 - 0x5415FFFE, // 0032 LDINT R5 -1 - 0xB81A1400, // 0033 GETNGBL R6 K10 - 0x88180D22, // 0034 GETMBR R6 R6 K34 - 0x14180806, // 0035 LT R6 R4 R6 - 0x781A000A, // 0036 JMPF R6 #0042 - 0x94180604, // 0037 GETIDX R6 R3 R4 - 0x1C1C0C00, // 0038 EQ R7 R6 R0 - 0x781E0000, // 0039 JMPF R7 #003B - 0x80040800, // 003A RET 1 R4 - 0x141C0D01, // 003B LT R7 R6 K1 - 0x781E0002, // 003C JMPF R7 #0040 - 0x141C0B01, // 003D LT R7 R5 K1 - 0x781E0000, // 003E JMPF R7 #0040 - 0x5C140800, // 003F MOVE R5 R4 - 0x00100907, // 0040 ADD R4 R4 K7 - 0x7001FFF0, // 0041 JMP #0033 - 0x28180B01, // 0042 GE R6 R5 K1 - 0x781A0001, // 0043 JMPF R6 #0046 - 0x980C0A00, // 0044 SETIDX R3 R5 R0 - 0x80040A00, // 0045 RET 1 R5 - 0xB0062726, // 0046 RAISE 1 K19 K38 - 0x80000000, // 0047 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: ctor -********************************************************************/ -be_local_closure(class_Leds_ctor, /* name */ +be_local_closure(class_Leds_clear_to, /* name */ be_nested_proto( 12, /* nstack */ 5, /* argc */ @@ -1961,35 +1599,301 @@ be_local_closure(class_Leds_ctor, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_ctor, + &be_const_str_clear_to, &be_const_str_solidified, - ( &(const binstruction[26]) { /* code */ + ( &(const binstruction[28]) { /* code */ 0x4C140000, // 0000 LDNIL R5 0x1C140405, // 0001 EQ R5 R2 R5 - 0x78160003, // 0002 JMPF R5 #0007 - 0x8C140106, // 0003 GETMET R5 R0 K6 - 0x581C0001, // 0004 LDCONST R7 K1 - 0x7C140400, // 0005 CALL R5 2 - 0x70020011, // 0006 JMP #0019 + 0x78160000, // 0002 JMPF R5 #0004 + 0x88080101, // 0003 GETMBR R2 R0 K1 + 0x4C140000, // 0004 LDNIL R5 + 0x20140605, // 0005 NE R5 R3 R5 + 0x7816000C, // 0006 JMPF R5 #0014 0x4C140000, // 0007 LDNIL R5 - 0x1C140605, // 0008 EQ R5 R3 R5 - 0x78160000, // 0009 JMPF R5 #000B - 0x880C0127, // 000A GETMBR R3 R0 K39 - 0x4C140000, // 000B LDNIL R5 - 0x1C140805, // 000C EQ R5 R4 R5 - 0x78160003, // 000D JMPF R5 #0012 - 0x8C140128, // 000E GETMET R5 R0 K40 - 0x5C1C0400, // 000F MOVE R7 R2 - 0x7C140400, // 0010 CALL R5 2 - 0x5C100A00, // 0011 MOVE R4 R5 - 0x8C140106, // 0012 GETMET R5 R0 K6 - 0x581C0001, // 0013 LDCONST R7 K1 - 0x5C200200, // 0014 MOVE R8 R1 - 0x5C240400, // 0015 MOVE R9 R2 - 0x5C280600, // 0016 MOVE R10 R3 - 0x5C2C0800, // 0017 MOVE R11 R4 - 0x7C140C00, // 0018 CALL R5 6 - 0x80000000, // 0019 RET 0 + 0x20140805, // 0008 NE R5 R4 R5 + 0x78160009, // 0009 JMPF R5 #0014 + 0x8C140100, // 000A GETMET R5 R0 K0 + 0x541E0008, // 000B LDINT R7 9 + 0x8C20010E, // 000C GETMET R8 R0 K14 + 0x5C280200, // 000D MOVE R10 R1 + 0x5C2C0400, // 000E MOVE R11 R2 + 0x7C200600, // 000F CALL R8 3 + 0x5C240600, // 0010 MOVE R9 R3 + 0x5C280800, // 0011 MOVE R10 R4 + 0x7C140A00, // 0012 CALL R5 5 + 0x70020006, // 0013 JMP #001B + 0x8C140100, // 0014 GETMET R5 R0 K0 + 0x541E0008, // 0015 LDINT R7 9 + 0x8C20010E, // 0016 GETMET R8 R0 K14 + 0x5C280200, // 0017 MOVE R10 R1 + 0x5C2C0400, // 0018 MOVE R11 R2 + 0x7C200600, // 0019 CALL R8 3 + 0x7C140600, // 001A CALL R5 3 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: create_segment +********************************************************************/ +be_local_closure(class_Leds_create_segment, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_create_segment, + &be_const_str_solidified, + ( &(const binstruction[23]) { /* code */ + 0x600C0009, // 0000 GETGBL R3 G9 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x60100009, // 0003 GETGBL R4 G9 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C100200, // 0005 CALL R4 1 + 0x000C0604, // 0006 ADD R3 R3 R4 + 0x8810010A, // 0007 GETMBR R4 R0 K10 + 0x240C0604, // 0008 GT R3 R3 R4 + 0x740E0003, // 0009 JMPT R3 #000E + 0x140C0305, // 000A LT R3 R1 K5 + 0x740E0001, // 000B JMPT R3 #000E + 0x140C0505, // 000C LT R3 R2 K5 + 0x780E0000, // 000D JMPF R3 #000F + 0xB006170C, // 000E RAISE 1 K11 K12 + 0x580C000F, // 000F LDCONST R3 K15 + 0xB400000F, // 0010 CLASS K15 + 0x5C100600, // 0011 MOVE R4 R3 + 0x5C140000, // 0012 MOVE R5 R0 + 0x5C180200, // 0013 MOVE R6 R1 + 0x5C1C0400, // 0014 MOVE R7 R2 + 0x7C100600, // 0015 CALL R4 3 + 0x80040800, // 0016 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_pixel_color +********************************************************************/ +be_local_closure(class_Leds_set_pixel_color, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_set_pixel_color, + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x1C100604, // 0001 EQ R4 R3 R4 + 0x78120000, // 0002 JMPF R4 #0004 + 0x880C0101, // 0003 GETMBR R3 R0 K1 + 0x8C100100, // 0004 GETMET R4 R0 K0 + 0x541A0009, // 0005 LDINT R6 10 + 0x5C1C0200, // 0006 MOVE R7 R1 + 0x8C20010E, // 0007 GETMET R8 R0 K14 + 0x5C280400, // 0008 MOVE R10 R2 + 0x5C2C0600, // 0009 MOVE R11 R3 + 0x7C200600, // 000A CALL R8 3 + 0x7C100800, // 000B CALL R4 4 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(class_Leds_init, /* name */ + be_nested_proto( + 12, /* nstack */ + 5, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_init, + &be_const_str_solidified, + ( &(const binstruction[43]) { /* code */ + 0xA4162000, // 0000 IMPORT R5 K16 + 0x50180200, // 0001 LDBOOL R6 1 0 + 0x90020E06, // 0002 SETMBR R0 K7 R6 + 0x4C180000, // 0003 LDNIL R6 + 0x1C180406, // 0004 EQ R6 R2 R6 + 0x741A0005, // 0005 JMPT R6 #000C + 0x8C180B11, // 0006 GETMET R6 R5 K17 + 0x88200B12, // 0007 GETMBR R8 R5 K18 + 0x58240005, // 0008 LDCONST R9 K5 + 0x7C180600, // 0009 CALL R6 3 + 0x1C180406, // 000A EQ R6 R2 R6 + 0x781A000A, // 000B JMPF R6 #0017 + 0x8C180113, // 000C GETMET R6 R0 K19 + 0x7C180200, // 000D CALL R6 1 + 0x8C180114, // 000E GETMET R6 R0 K20 + 0x7C180200, // 000F CALL R6 1 + 0x90021406, // 0010 SETMBR R0 K10 R6 + 0xA41A2A00, // 0011 IMPORT R6 K21 + 0x8C1C0D16, // 0012 GETMET R7 R6 K22 + 0x7C1C0200, // 0013 CALL R7 1 + 0x941C0F01, // 0014 GETIDX R7 R7 K1 + 0x90020207, // 0015 SETMBR R0 K1 R7 + 0x7002000B, // 0016 JMP #0023 + 0x60180009, // 0017 GETGBL R6 G9 + 0x5C1C0200, // 0018 MOVE R7 R1 + 0x7C180200, // 0019 CALL R6 1 + 0x90021406, // 001A SETMBR R0 K10 R6 + 0x541A007E, // 001B LDINT R6 127 + 0x90020206, // 001C SETMBR R0 K1 R6 + 0x8C180113, // 001D GETMET R6 R0 K19 + 0x8820010A, // 001E GETMBR R8 R0 K10 + 0x5C240400, // 001F MOVE R9 R2 + 0x5C280600, // 0020 MOVE R10 R3 + 0x5C2C0800, // 0021 MOVE R11 R4 + 0x7C180A00, // 0022 CALL R6 5 + 0x88180117, // 0023 GETMBR R6 R0 K23 + 0x4C1C0000, // 0024 LDNIL R7 + 0x1C180C07, // 0025 EQ R6 R6 R7 + 0x781A0000, // 0026 JMPF R6 #0028 + 0xB0063119, // 0027 RAISE 1 K24 K25 + 0x8C18011A, // 0028 GETMET R6 R0 K26 + 0x7C180200, // 0029 CALL R6 1 + 0x80000000, // 002A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: clear +********************************************************************/ +be_local_closure(class_Leds_clear, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_clear, + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x8C04011B, // 0000 GETMET R1 R0 K27 + 0x580C0005, // 0001 LDCONST R3 K5 + 0x7C040400, // 0002 CALL R1 2 + 0x8C04011C, // 0003 GETMET R1 R0 K28 + 0x7C040200, // 0004 CALL R1 1 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: begin +********************************************************************/ +be_local_closure(class_Leds_begin, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_begin, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x580C001D, // 0001 LDCONST R3 K29 + 0x7C040400, // 0002 CALL R1 2 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pixel_count +********************************************************************/ +be_local_closure(class_Leds_pixel_count, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_pixel_count, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0007, // 0001 LDINT R3 8 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: to_gamma +********************************************************************/ +be_local_closure(class_Leds_to_gamma, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_to_gamma, + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E0000, // 0002 JMPF R3 #0004 + 0x88080101, // 0003 GETMBR R2 R0 K1 + 0x8C0C011E, // 0004 GETMET R3 R0 K30 + 0x5C140200, // 0005 MOVE R5 R1 + 0x5C180400, // 0006 MOVE R6 R2 + 0x881C0107, // 0007 GETMBR R7 R0 K7 + 0x7C0C0800, // 0008 CALL R3 4 + 0x80040600, // 0009 RET 1 R3 }) ) ); @@ -2013,7 +1917,7 @@ be_local_closure(class_Leds_pixels_buffer, /* name */ &be_const_str_pixels_buffer, &be_const_str_solidified, ( &(const binstruction[21]) { /* code */ - 0x8C080106, // 0000 GETMET R2 R0 K6 + 0x8C080100, // 0000 GETMET R2 R0 K0 0x54120005, // 0001 LDINT R4 6 0x7C080400, // 0002 CALL R2 2 0x4C0C0000, // 0003 LDNIL R3 @@ -2021,15 +1925,15 @@ be_local_closure(class_Leds_pixels_buffer, /* name */ 0x780E0009, // 0005 JMPF R3 #0010 0x600C0015, // 0006 GETGBL R3 G21 0x5C100400, // 0007 MOVE R4 R2 - 0x8C140129, // 0008 GETMET R5 R0 K41 + 0x8C14011F, // 0008 GETMET R5 R0 K31 0x7C140200, // 0009 CALL R5 1 - 0x8C18010F, // 000A GETMET R6 R0 K15 + 0x8C180114, // 000A GETMET R6 R0 K20 0x7C180200, // 000B CALL R6 1 0x08140A06, // 000C MUL R5 R5 R6 0x7C0C0400, // 000D CALL R3 2 0x80040600, // 000E RET 1 R3 0x70020003, // 000F JMP #0014 - 0x8C0C032A, // 0010 GETMET R3 R1 K42 + 0x8C0C0320, // 0010 GETMET R3 R1 K32 0x5C140400, // 0011 MOVE R5 R2 0x7C0C0400, // 0012 CALL R3 2 0x80040200, // 0013 RET 1 R1 @@ -2047,35 +1951,34 @@ extern const bclass be_class_Leds_ntv; be_local_class(Leds, 3, &be_class_Leds_ntv, - be_nested_map(27, + be_nested_map(26, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(leds, -1), be_const_var(1) }, - { be_const_key(create_segment, 25), be_const_closure(class_Leds_create_segment_closure) }, - { be_const_key(clear, -1), be_const_closure(class_Leds_clear_closure) }, - { be_const_key(begin, -1), be_const_closure(class_Leds_begin_closure) }, - { be_const_key(ctor, 7), be_const_closure(class_Leds_ctor_closure) }, - { be_const_key(assign_rmt, 12), be_const_static_closure(class_Leds_assign_rmt_closure) }, - { be_const_key(to_gamma, 8), be_const_closure(class_Leds_to_gamma_closure) }, - { be_const_key(dirty, -1), be_const_closure(class_Leds_dirty_closure) }, - { be_const_key(matrix, -1), be_const_static_closure(class_Leds_matrix_closure) }, - { be_const_key(pixel_offset, 2), be_const_closure(class_Leds_pixel_offset_closure) }, - { be_const_key(set_gamma, 4), be_const_closure(class_Leds_set_gamma_closure) }, - { be_const_key(get_pixel_color, -1), be_const_closure(class_Leds_get_pixel_color_closure) }, - { be_const_key(pixel_size, -1), be_const_closure(class_Leds_pixel_size_closure) }, - { be_const_key(create_matrix, -1), be_const_closure(class_Leds_create_matrix_closure) }, - { be_const_key(set_bri, 9), be_const_closure(class_Leds_set_bri_closure) }, - { be_const_key(clear_to, -1), be_const_closure(class_Leds_clear_to_closure) }, - { be_const_key(set_pixel_color, -1), be_const_closure(class_Leds_set_pixel_color_closure) }, - { be_const_key(gamma, -1), be_const_var(0) }, - { be_const_key(pixel_count, 17), be_const_closure(class_Leds_pixel_count_closure) }, - { be_const_key(get_bri, 13), be_const_closure(class_Leds_get_bri_closure) }, - { be_const_key(get_gamma, -1), be_const_closure(class_Leds_get_gamma_closure) }, - { be_const_key(bri, -1), be_const_var(2) }, { be_const_key(is_dirty, -1), be_const_closure(class_Leds_is_dirty_closure) }, - { be_const_key(can_show, -1), be_const_closure(class_Leds_can_show_closure) }, - { be_const_key(init, 5), be_const_closure(class_Leds_init_closure) }, - { be_const_key(show, -1), be_const_closure(class_Leds_show_closure) }, { be_const_key(pixels_buffer, -1), be_const_closure(class_Leds_pixels_buffer_closure) }, + { be_const_key(to_gamma, -1), be_const_closure(class_Leds_to_gamma_closure) }, + { be_const_key(can_show, -1), be_const_closure(class_Leds_can_show_closure) }, + { be_const_key(pixel_offset, -1), be_const_closure(class_Leds_pixel_offset_closure) }, + { be_const_key(set_bri, 24), be_const_closure(class_Leds_set_bri_closure) }, + { be_const_key(show, 2), be_const_closure(class_Leds_show_closure) }, + { be_const_key(ctor, -1), be_const_closure(class_Leds_ctor_closure) }, + { be_const_key(begin, 22), be_const_closure(class_Leds_begin_closure) }, + { be_const_key(leds, -1), be_const_var(1) }, + { be_const_key(set_pixel_color, -1), be_const_closure(class_Leds_set_pixel_color_closure) }, + { be_const_key(dirty, 4), be_const_closure(class_Leds_dirty_closure) }, + { be_const_key(get_pixel_color, -1), be_const_closure(class_Leds_get_pixel_color_closure) }, + { be_const_key(get_gamma, -1), be_const_closure(class_Leds_get_gamma_closure) }, + { be_const_key(gamma, -1), be_const_var(0) }, + { be_const_key(create_matrix, -1), be_const_closure(class_Leds_create_matrix_closure) }, + { be_const_key(matrix, 8), be_const_static_closure(class_Leds_matrix_closure) }, + { be_const_key(create_segment, -1), be_const_closure(class_Leds_create_segment_closure) }, + { be_const_key(bri, 10), be_const_var(2) }, + { be_const_key(init, -1), be_const_closure(class_Leds_init_closure) }, + { be_const_key(clear, -1), be_const_closure(class_Leds_clear_closure) }, + { be_const_key(get_bri, 9), be_const_closure(class_Leds_get_bri_closure) }, + { be_const_key(clear_to, -1), be_const_closure(class_Leds_clear_to_closure) }, + { be_const_key(pixel_count, -1), be_const_closure(class_Leds_pixel_count_closure) }, + { be_const_key(set_gamma, -1), be_const_closure(class_Leds_set_gamma_closure) }, + { be_const_key(pixel_size, 1), be_const_closure(class_Leds_pixel_size_closure) }, })), (bstring*) &be_const_str_Leds ); diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 5af1f9aaa..b2873e8df 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -562,14 +562,7 @@ // #define MAGICSWITCH_MASKING_WINDOW_LEN 5 // Overridable masking window (in number of 50ms loops) // -- Optional light modules ---------------------- -#define USE_LIGHT // Add support for light control -#define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // -// #define USE_WS2812_DMA // ESP8266 only, DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow - #define USE_WS2812_RMT 0 // ESP32 only, hardware RMT support (default). Specify the RMT channel 0..7. This should be preferred to software bit bang. -// #define USE_WS2812_I2S 0 // ESP32 only, hardware I2S support. Specify the I2S channel 0..2. This is exclusive from RMT. By default, prefer RMT support -// #define USE_WS2812_INVERTED // Use inverted data signal - #define USE_WS2812_HARDWARE NEO_HW_WS2812 // Hardware type (NEO_HW_WS2812, NEO_HW_WS2812X, NEO_HW_WS2813, NEO_HW_SK6812, NEO_HW_LC8812, NEO_HW_APA106, NEO_HW_P9813) - #define USE_WS2812_CTYPE NEO_GRB // Color type (NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_RGBW, NEO_GRBW) +#define USE_LIGHT // Add support for light control #define USE_MY92X1 // Add support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas #define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code) #define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) @@ -583,6 +576,18 @@ #define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code) //#define USE_LSC_MCSL // Add support for GPE Multi color smart light as sold by Action in the Netherlands (+1k1 code) +// -- Optional adressable leds ---------------------- +#define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // +// -------- below is for ESP8266 only +// #define USE_WS2812_DMA // ESP8266 only, DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow + #define USE_WS2812_RMT 0 // ESP32 only, hardware RMT support (default). Specify the RMT channel 0..7. This should be preferred to software bit bang. +// #define USE_WS2812_I2S 0 // ESP32 only, hardware I2S support. Specify the I2S channel 0..2. This is exclusive from RMT. By default, prefer RMT support +// #define USE_WS2812_INVERTED // Use inverted data signal + #define USE_WS2812_HARDWARE NEO_HW_WS2812 // Hardware type (NEO_HW_WS2812, NEO_HW_WS2812X, NEO_HW_WS2813, NEO_HW_SK6812, NEO_HW_LC8812, NEO_HW_APA106, NEO_HW_P9813) + #define USE_WS2812_CTYPE NEO_GRB // Color type (NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_RGBW, NEO_GRBW) +// -------- below if for ESP32x only -- ESP32 uses a lightweight library instead of NeoPixelBus + // #define USE_WS2812_FORCE_NEOPIXELBUS // this option forces to use NeoPixelBus (like ESP866), which disables Berry support and limits features -- DO NOT USE unless you have a good reason + // #define USE_LIGHT_ARTNET // Add support for DMX/ArtNet via UDP on port 6454 (+3.5k code) #define USE_LIGHT_ARTNET_MCAST 239,255,25,54 // Multicast address used to listen: 239.255.25.54 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino index d0d3b61ff..142044766 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino @@ -386,7 +386,7 @@ bool ArtNetStart(void) { Settings->light_rotation = 0; Ws2812InitStrip(); } else { - Ws2812Clear(); + Ws2812Clear(true); } } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino index 0984cb14b..a06890b09 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino @@ -24,22 +24,8 @@ #ifdef USE_WS2812 -#include - -enum { - ws2812_grb = 1, - sk6812_grbw = 2, - - neopixel_type_end -}; - -#ifdef CONFIG_IDF_TARGET_ESP32C2 -typedef NeoPixelBus neopixel_ws2812_grb_t; -typedef NeoPixelBus neopixel_sk6812_grbw_t; -#else -typedef NeoPixelBus neopixel_ws2812_grb_t; -typedef NeoPixelBus neopixel_sk6812_grbw_t; -#endif +#include "TasmotaLED.h" +#include "TasmotaLEDPusher.h" /*********************************************************************************************\ * Functions from Tasmota WS2812 driver @@ -86,12 +72,12 @@ extern "C" { // # 22 : ShiftLeft (rot:int [, first:int, last:int]) -> void // # 23 : ShiftRight (rot:int [, first:int, last:int]) -> void - void * be_get_neopixelbus(bvm *vm) { + void * be_get_tasmotaled(bvm *vm) { be_getmember(vm, 1, "_p"); void * strip = (void*) be_tocomptr(vm, -1); be_pop(vm, 1); if (strip == nullptr) { - be_raise(vm, "internal_error", "neopixelbus object not initialized"); + be_raise(vm, "internal_error", "tasmotaled object not initialized"); } return strip; } @@ -99,70 +85,65 @@ extern "C" { be_getmember(vm, 1, "_t"); int32_t type = be_toint(vm, -1); be_pop(vm, 1); - if (type < 0 || type >= neopixel_type_end) { + if (type < 0) { be_raise(vm, "internal_error", "invalid leds type"); } return type; } - int be_neopixelbus_call_native(bvm *vm); - int be_neopixelbus_call_native(bvm *vm) { + int be_tasmotaled_call_native(bvm *vm); + int be_tasmotaled_call_native(bvm *vm) { int32_t argc = be_top(vm); // Get the number of arguments if (argc >= 2 && be_isint(vm, 2)) { int32_t cmd = be_toint(vm, 2); if (0 == cmd) { // 00 : ctor (leds:int, gpio:int) -> void - if ((argc != 2) && !(argc >= 6 && be_isint(vm, 3) && be_isint(vm, 4) && be_isint(vm, 5) && be_isint(vm, 6))) { - be_raise(vm, "value_error", "bad arguments for neopixelbus:ctor"); + if ((argc != 2) && !(argc >= 5 && be_isint(vm, 3) && be_isint(vm, 4) && be_isint(vm, 5))) { + be_raise(vm, "value_error", "bad arguments for tasmotaled:ctor"); } int32_t leds = -1; int32_t gpio = -1; - int32_t neopixel_type = 0; - int32_t rmt = 0; - void * strip = nullptr; + int32_t led_type = 0; + int32_t hardware = 0; + if (argc >= 6 && be_isint(vm, 6)) { + hardware = be_toint(vm, 6) & 0xFF0000; // remove the low 16 bits to avoid any interference with legacy parameter for RMT channels + } + TasmotaLED * strip = nullptr; if (argc > 2) { leds = be_toint(vm, 3); gpio = be_toint(vm, 4); - neopixel_type = be_toint(vm, 5); - rmt = be_toint(vm, 6); + led_type = be_toint(vm, 5); } if (-1 == gpio) { // if GPIO is '-1' - neopixel_type = 0; - Ws2812InitStrip(); // ensure the NeoPixelbus object is initialized, because Berry code runs before the driver is initialized - strip = Ws2812GetStrip(); + led_type = 0; + Ws2812InitStrip(); // ensure the tasmotaled object is initialized, because Berry code runs before the driver is initialized + // strip = Ws2812GetStrip(); TODO } else { - // allocate a new RMT - if (neopixel_type < 1) { neopixel_type = 1; } - if (neopixel_type >= neopixel_type_end) { neopixel_type = neopixel_type_end - 1; } - if (rmt < 0) { rmt = 0; } - if (rmt >= MAX_RMT) { rmt = MAX_RMT - 1; } - - switch (neopixel_type) { - case ws2812_grb: strip = new neopixel_ws2812_grb_t(leds, gpio, (NeoBusChannel) rmt); - break; - case sk6812_grbw: strip = new neopixel_sk6812_grbw_t(leds, gpio, (NeoBusChannel) rmt); - break; + if (led_type < 1) { led_type = 1; } + TasmotaLEDPusher * pusher = TasmotaLEDPusher::Create(hardware, gpio); + if (pusher == nullptr) { + be_raise(vm, "value_error", "LED interface not supported"); } + strip = new TasmotaLED(led_type, leds); + strip->SetPusher(pusher); } + // AddLog(LOG_LEVEL_DEBUG, "LED: leds %i gpio %i type %i", leds, gpio, led_type); // store type in attribute `_t` - be_pushint(vm, neopixel_type); + be_pushint(vm, led_type); be_setmember(vm, 1, "_t"); be_pop(vm, 1); - be_pushcomptr(vm, (void*) strip); + be_pushcomptr(vm, (void*) strip); // if native driver, it is NULL be_setmember(vm, 1, "_p"); be_pop(vm, 1); be_pushnil(vm); } else { - // all other commands need a valid neopixelbus pointer + // all other commands need a valid tasmotaled pointer int32_t leds_type = be_get_leds_type(vm); - const void * s = be_get_neopixelbus(vm); // raises an exception if pointer is invalid - // initialize all possible variants - neopixel_ws2812_grb_t * s_ws2812_grb = (leds_type == ws2812_grb) ? (neopixel_ws2812_grb_t*) s : nullptr; - neopixel_sk6812_grbw_t * s_sk6812_grbw = (leds_type == sk6812_grbw) ? (neopixel_sk6812_grbw_t*) s : nullptr; + TasmotaLED * strip = (TasmotaLED*) be_get_tasmotaled(vm); // raises an exception if pointer is invalid // detect native driver bool native = (leds_type == 0); @@ -171,8 +152,7 @@ extern "C" { switch (cmd) { case 1: // # 01 : begin void -> void if (native) Ws2812Begin(); - if (s_ws2812_grb) s_ws2812_grb->Begin(); - if (s_sk6812_grbw) s_sk6812_grbw->Begin(); + else if (strip) strip->Begin(); break; case 2: // # 02 : show void -> void { @@ -195,49 +175,50 @@ extern "C" { } } uint32_t pixels_size; // number of bytes to push - if (native) { Ws2812Show(); pixels_size = Ws2812PixelsSize(); } - if (s_ws2812_grb) { s_ws2812_grb->Show(); pixels_size = s_ws2812_grb->PixelsSize(); } - if (s_sk6812_grbw) { s_sk6812_grbw->Show(); pixels_size = s_sk6812_grbw->PixelsSize(); } + bool update_completed = false; + if (native) { + Ws2812Show(); + pixels_size = Ws2812PixelsSize(); + update_completed =Ws2812CanShow(); + } + else if (strip) { + strip->Show(); + pixels_size = strip->PixelCount() * strip->PixelSize(); + update_completed = strip->CanShow(); + } // Wait for RMT/I2S to complete fixes distortion due to analogRead // 1ms is needed for 96 bytes - SystemBusyDelay((pixels_size + 95) / 96); + if (!update_completed) { + SystemBusyDelay((pixels_size + 95) / 96); + } } break; case 3: // # 03 : CanShow void -> bool if (native) be_pushbool(vm, Ws2812CanShow()); - if (s_ws2812_grb) be_pushbool(vm, s_ws2812_grb->CanShow()); - if (s_sk6812_grbw) be_pushbool(vm, s_sk6812_grbw->CanShow()); + else if (strip) be_pushbool(vm, strip->CanShow()); break; case 4: // # 04 : IsDirty void -> bool if (native) be_pushbool(vm, Ws2812IsDirty()); - if (s_ws2812_grb) be_pushbool(vm, s_ws2812_grb->IsDirty()); - if (s_sk6812_grbw) be_pushbool(vm, s_sk6812_grbw->IsDirty()); + else if (strip) be_pushbool(vm, strip->IsDirty()); break; case 5: // # 05 : Dirty void -> void if (native) Ws2812Dirty(); - if (s_ws2812_grb) s_ws2812_grb->Dirty(); - if (s_sk6812_grbw) s_sk6812_grbw->Dirty(); + else if (strip) strip->Dirty(); break; case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer) { - uint8_t * pixels; - if (native) pixels = Ws2812Pixels(); - if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels(); - if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels(); - - be_pushcomptr(vm, pixels); + if (native) be_pushcomptr(vm, Ws2812Pixels()); + else if (strip) be_pushcomptr(vm, strip->Pixels()); } break; case 7: // # 07 : PixelSize void -> int if (native) be_pushint(vm, Ws2812PixelSize()); - if (s_ws2812_grb) be_pushint(vm, s_ws2812_grb->PixelSize()); - if (s_sk6812_grbw) be_pushint(vm, s_sk6812_grbw->PixelSize()); + else if (strip) be_pushint(vm, strip->PixelSize()); break; case 8: // # 08 : PixelCount void -> int if (native) be_pushint(vm, Ws2812PixelCount()); - if (s_ws2812_grb) be_pushint(vm, s_ws2812_grb->PixelCount()); - if (s_sk6812_grbw) be_pushint(vm, s_sk6812_grbw->PixelCount()); + else if (strip) be_pushint(vm, strip->PixelCount()); break; case 9: // # 09 : ClearTo (color:??) -> void { @@ -253,42 +234,35 @@ extern "C" { if (len < 0) { len = 0; } if (native) Ws2812ClearTo(r, g, b, w, from, from + len - 1); - if (s_ws2812_grb) s_ws2812_grb->ClearTo(RgbColor(r, g, b), from, from + len - 1); - if (s_sk6812_grbw) s_sk6812_grbw->ClearTo(RgbwColor(r, g, b, w), from, from + len - 1); + else if (strip) strip->ClearTo(rgbw, from, from + len - 1); } else { if (native) Ws2812ClearTo(r, g, b, w, -1, -1); - if (s_ws2812_grb) s_ws2812_grb->ClearTo(RgbColor(r, g, b)); - if (s_sk6812_grbw) s_sk6812_grbw->ClearTo(RgbwColor(r, g, b, w)); + else if (strip) strip->ClearTo(rgbw); } } break; - case 10: // # 10 : SetPixelColor (idx:int, color:??) -> void + case 10: // # 10 : SetPixelColor (idx:int, color:int wrgb) -> void { int32_t idx = be_toint(vm, 3); - uint32_t rgbw = be_toint(vm, 4); - uint8_t w = (rgbw >> 24) & 0xFF; - uint8_t r = (rgbw >> 16) & 0xFF; - uint8_t g = (rgbw >> 8) & 0xFF; - uint8_t b = (rgbw ) & 0xFF; - if (native) Ws2812SetPixelColor(idx, r, g, b, w); - if (s_ws2812_grb) s_ws2812_grb->SetPixelColor(idx, RgbColor(r, g, b)); - if (s_sk6812_grbw) s_sk6812_grbw->SetPixelColor(idx, RgbwColor(r, g, b, w)); + uint32_t wrgb = be_toint(vm, 4); + if (native) { + uint8_t w = (wrgb >> 24) & 0xFF; + uint8_t r = (wrgb >> 16) & 0xFF; + uint8_t g = (wrgb >> 8) & 0xFF; + uint8_t b = (wrgb ) & 0xFF; + Ws2812SetPixelColor(idx, r, g, b, w); + } else if (strip) { + strip->SetPixelColor(idx, wrgb); + } } break; - case 11: // # 11 : GetPixelColor (idx:int) -> color:?? + case 11: // # 11 : GetPixelColor (idx:int) -> color:int wrgb { int32_t idx = be_toint(vm, 3); - if (native) { be_pushint(vm, Ws2812GetPixelColor(idx)); - } - if (s_ws2812_grb) { - RgbColor rgb = s_ws2812_grb->GetPixelColor(idx); - be_pushint(vm, (rgb.R << 16) | (rgb.G << 8) | rgb.B); - } - if (s_sk6812_grbw) { - RgbwColor rgbw = s_sk6812_grbw->GetPixelColor(idx); - be_pushint(vm, (rgbw.W << 24) | (rgbw.R << 16) | (rgbw.G << 8) | rgbw.B); + } else if (strip) { + be_pushint(vm, strip->GetPixelColor(idx)); } } break; diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino index b05d15e8a..9be3d3117 100644 --- a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino +++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino @@ -17,6 +17,7 @@ along with this program. If not, see . */ +#if defined(ESP8266) || defined(USE_WS2812_FORCE_NEOPIXELBUS) #ifdef USE_LIGHT #ifdef USE_WS2812 @@ -553,11 +554,14 @@ void Ws2812DDP(void) } #endif // USE_NETWORK_LIGHT_SCHEMES -void Ws2812Clear(void) +void Ws2812Clear(bool display = true); +void Ws2812Clear(bool display) { strip->ClearTo(0); - Ws2812LibStripShow(); - Ws2812.show_next = 1; + if (display) { + Ws2812LibStripShow(); + Ws2812.show_next = 1; + } } void Ws2812SetColor(uint32_t led, uint8_t red, uint8_t green, uint8_t blue, uint8_t white) @@ -965,3 +969,4 @@ bool Xlgt01(uint32_t function) #endif // USE_WS2812 #endif // USE_LIGHT +#endif // defined(ESP8266) || defined(USE_WS2812_FORCE_NEOPIXELBUS) diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino new file mode 100644 index 000000000..5ff5d94dd --- /dev/null +++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino @@ -0,0 +1,899 @@ +/* + xlgt_01_ws2812.ino - led string 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 ESP32 +#ifdef USE_LIGHT +#if defined(USE_WS2812) && !defined(USE_WS2812_FORCE_NEOPIXELBUS) + +/*********************************************************************************************\ + * WS2812 RGB / RGBW Leds using NeopixelBus library + * + * light_scheme WS2812 3+ Colors 1+2 Colors Effect + * ------------ ------ --------- ---------- ----------------- + * 0 (5) yes no no Clock + * 1 (6) yes no no Incandescent + * 2 (7) yes no no RGB + * 3 (8) yes no no Christmas + * 4 (9) yes no no Hanukkah + * 5 (10) yes no no Kwanzaa + * 6 (11) yes no no Rainbow + * 7 (12) yes no no Fire + * 8 (13) yes no no Stairs + * 9 (14) yes no no Clear (= Berry) + * 10 (15) yes no no Optional DDP +\*********************************************************************************************/ + +#define XLGT_01 1 + +const uint8_t WS2812_SCHEMES = 10; // Number of WS2812 schemes + +const char kWs2812Commands[] PROGMEM = "|" // No prefix + D_CMND_LED "|" D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_WIDTH "|" D_CMND_STEPPIXELS ; + +void (* const Ws2812Command[])(void) PROGMEM = { + &CmndLed, &CmndPixels, &CmndRotation, &CmndWidth, &CmndStepPixels }; + +#include + +const uint16_t kLedType = 0; +// select the right pixel size +#if (USE_WS2812_CTYPE > NEO_3LED) + const uint16_t kTasLed_PixelSize = TasmotaLed_4_WRGB; +#else + const uint16_t kTasLed_PixelSize = TasmotaLed_3_RGB; +#endif + +// select the right pixel order +#if (USE_WS2812_CTYPE == NEO_GRB) + const uint16_t kTasLed_PixelOrder = TasmotaLed_GRB; +#elif (USE_WS2812_CTYPE == NEO_BRG) + const uint16_t kTasLed_PixelOrder = TasmotaLed_BRG; +#elif (USE_WS2812_CTYPE == NEO_RBG) + const uint16_t kTasLed_PixelOrder = TasmotaLed_RBG; + #elif (USE_WS2812_CTYPE == NEO_RGBW) + const uint16_t kTasLed_PixelOrder = TasmotaLed_RGB; +#elif (USE_WS2812_CTYPE == NEO_GRBW) + const uint16_t kTasLed_PixelOrder = TasmotaLed_GRB; +#else + const uint16_t kTasLed_PixelOrder = TasmotaLed_RGB; +#endif + +// all leds have always W at the end +const uint16_t kTasLed_PixelWhite = TasmotaLed_xxxW; + +// We drop support for NEO_HW_P9813, as it is too hard to support with hardwarre +#if (USE_WS2812_HARDWARE == NEO_HW_P9813) + #error "P9813 is not supported by this library" +#endif // USE_WS2812_CTYPE + +// select timing +#if (USE_WS2812_HARDWARE == NEO_HW_WS2812X) + const uint16_t kTasLed_Timing = TasmotaLed_WS2812; +#elif (USE_WS2812_HARDWARE == NEO_HW_SK6812) + const uint16_t kTasLed_Timing = TasmotaLed_SK6812; +#elif (USE_WS2812_HARDWARE == NEO_HW_APA106) + #error "APA106 is not supported by this library" +#else // USE_WS2812_HARDWARE + const uint16_t kTasLed_Timing = TasmotaLed_WS2812; +#endif // USE_WS2812_HARDWARE + +const uint16_t kTasLed_Type = kTasLed_PixelSize | kTasLed_PixelOrder | kTasLed_PixelWhite | kTasLed_Timing; + +// select hardware acceleration - bitbanging is not supported on ESP32 due to interference of interrupts +#if CONFIG_IDF_TARGET_ESP32C2 + const uint32_t kTasLed_Hardware = TasmotaLed_I2S; // I2S +#else // all other ESP32 variants + #if defined(USE_WS2812_DMA) + const uint32_t kTasLed_Hardware = TasmotaLed_RMT; // default DMA to RMT + #elif defined(USE_WS2812_RMT) + const uint32_t kTasLed_Hardware = TasmotaLed_RMT; // default DMA to RMT + #elif defined(USE_WS2812_I2S) + const uint32_t kTasLed_Hardware = TasmotaLed_I2S; // I2S + #else + const uint32_t kTasLed_Hardware = TasmotaLed_RMT; // default DMA to RMT + #endif +#endif + +#if (USE_WS2812_HARDWARE == NEO_HW_P9813) + #error "P9813 is not supported by this library" +#endif + + +/*******************************************************************************************\ + * Support for TasmotaLED + * + * From here we have defined: + * kTasLed_Type: encodes pixel size, pixel order, pixel white, timing + * kTasLed_Hardware: encodes the harware support to push to Leds: RMT, SPI, I2S + *******************************************************************************************/ +TasmotaLED *strip = nullptr; + +typedef union LedColor { + uint32_t C; // encoded as 0xWWRRGGBB + struct { + uint8_t B, G, R, W; // WRGB in little endian + }; +} LedColor; + +struct ColorScheme { + const LedColor* colors; + uint8_t count; +}; + +const LedColor kIncandescent[2] = { 0xFF8C14, 0x000000 }; +const LedColor kRgb[3] = { 0xFF0000, 0x00FF00, 0x0000FF }; +const LedColor kChristmas[2] = { 0xFF0000, 0x00FF00 }; +const LedColor kHanukkah[2] = { 0x0000FF, 0xFFFFFF }; +const LedColor kwanzaa[3] = { 0xFF0000, 0x000000, 0x00FF00 }; +const LedColor kRainbow[7] = { 0xFF0000, 0xFF8000, 0xFFFF00, 0x00FF00, 0x0000FF, 0x8000FF, 0xFF00FF }; +const LedColor kFire[3] = { 0xFF0000, 0xFF6600, 0xFFC000 }; +const LedColor kStairs[2] = { 0x000000, 0xFFFFFF0 }; + +const ColorScheme kSchemes[WS2812_SCHEMES -2] = { // Skip clock and clear scheme + kIncandescent, 2, + kRgb, 3, + kChristmas, 2, + kHanukkah, 2, + kwanzaa, 3, + kRainbow, 7, + kFire, 3, + kStairs, 2 +}; + +const uint8_t kWidth[5] = { + 1, // Small + 2, // Medium + 4, // Large + 8, // Largest + 255 // All +}; +const uint8_t kWsRepeat[5] = { + 8, // Small + 6, // Medium + 4, // Large + 2, // Largest + 1 // All +}; + +struct WS2812 { + uint8_t show_next = 1; + uint8_t scheme_offset = 0; + bool suspend_update = false; +} Ws2812; + +/********************************************************************************************/ + +// For some reason map fails to compile so renamed to wsmap +long wsmap(long x, long in_min, long in_max, long out_min, long out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +void Ws2812LibStripShow(void) { + strip->Show(); + +#if defined(USE_WS2812_DMA) || defined(USE_WS2812_RMT) || defined(USE_WS2812_I2S) + // Wait for DMA/RMT/I2S to complete fixes distortion due to analogRead +// delay((Settings->light_pixels >> 6) +1); // 256 / 64 = 4 +1 = 5 + SystemBusyDelay( (Settings->light_pixels + 31) >> 5); // (256 + 32) / 32 = 8 +#endif +} + +void Ws2812StripShow(void) +{ + LedColor c; + + if (Settings->light_correction) { + for (uint32_t i = 0; i < Settings->light_pixels; i++) { + c.C = strip->GetPixelColor(i); + c.R = ledGamma(c.R); + c.G = ledGamma(c.G); + c.B = ledGamma(c.B); +#if (USE_WS2812_CTYPE > NEO_3LED) + c.W = ledGamma(c.W); +#endif + strip->SetPixelColor(i, c.C); + } + } + Ws2812LibStripShow(); +} + +int mod(int a, int b) +{ + int ret = a % b; + if (ret < 0) ret += b; + return ret; +} + +void Ws2812UpdatePixelColor(int position, LedColor hand_color, float offset); +void Ws2812UpdatePixelColor(int position, LedColor hand_color, float offset) +{ + LedColor color; + + uint32_t mod_position = mod(position, (int)Settings->light_pixels); + + color.C = strip->GetPixelColor(mod_position); + float dimmer = 100 / (float)Settings->light_dimmer; + color.R = tmin(color.R + ((hand_color.R / dimmer) * offset), 255); + color.G = tmin(color.G + ((hand_color.G / dimmer) * offset), 255); + color.B = tmin(color.B + ((hand_color.B / dimmer) * offset), 255); + strip->SetPixelColor(mod_position, color.C); +} + +void Ws2812UpdateHand(int position, uint32_t index) +{ + uint32_t width = Settings->light_width; + if (index < WS_MARKER) { width = Settings->ws_width[index]; } + if (!width) { return; } // Skip + + position = (position + Settings->light_rotation) % Settings->light_pixels; + + if (Settings->flag.ws_clock_reverse) { // SetOption16 - Switch between clockwise or counter-clockwise + position = Settings->light_pixels -position; + } + LedColor hand_color = {0}; + hand_color.R = Settings->ws_color[index][WS_RED]; + hand_color.G = Settings->ws_color[index][WS_GREEN]; + hand_color.B = Settings->ws_color[index][WS_BLUE]; + + Ws2812UpdatePixelColor(position, hand_color, 1); + + uint32_t range = ((width -1) / 2) +1; + for (uint32_t h = 1; h < range; h++) { + float offset = (float)(range - h) / (float)range; + Ws2812UpdatePixelColor(position -h, hand_color, offset); + Ws2812UpdatePixelColor(position +h, hand_color, offset); + } +} + +void Ws2812Clock(void) +{ + strip->ClearTo(0); // Reset strip + int clksize = 60000 / (int)Settings->light_pixels; + + Ws2812UpdateHand((RtcTime.second * 1000) / clksize, WS_SECOND); + Ws2812UpdateHand((RtcTime.minute * 1000) / clksize, WS_MINUTE); + Ws2812UpdateHand((((RtcTime.hour % 12) * 5000) + ((RtcTime.minute * 1000) / 12 )) / clksize, WS_HOUR); + if (Settings->ws_color[WS_MARKER][WS_RED] + Settings->ws_color[WS_MARKER][WS_GREEN] + Settings->ws_color[WS_MARKER][WS_BLUE]) { + for (uint32_t i = 0; i < 12; i++) { + Ws2812UpdateHand((i * 5000) / clksize, WS_MARKER); + } + } + + Ws2812StripShow(); +} + +void Ws2812GradientColor(uint32_t schemenr, LedColor* mColor, uint32_t range, uint32_t gradRange, uint32_t i); +void Ws2812GradientColor(uint32_t schemenr, LedColor* mColor, uint32_t range, uint32_t gradRange, uint32_t i) +{ +/* + * Compute the color of a pixel at position i using a gradient of the color scheme. + * This function is used internally by the gradient function. + */ + ColorScheme scheme = kSchemes[schemenr]; + uint32_t curRange = i / range; + uint32_t rangeIndex = i % range; + uint32_t colorIndex = rangeIndex / gradRange; + uint32_t start = colorIndex; + uint32_t end = colorIndex +1; + if (curRange % 2 != 0) { + start = (scheme.count -1) - start; + end = (scheme.count -1) - end; + } + float dimmer = 100 / (float)Settings->light_dimmer; + float fmyRed = (float)wsmap(rangeIndex % gradRange, 0, gradRange, scheme.colors[start].R, scheme.colors[end].R) / dimmer; + float fmyGrn = (float)wsmap(rangeIndex % gradRange, 0, gradRange, scheme.colors[start].G, scheme.colors[end].G) / dimmer; + float fmyBlu = (float)wsmap(rangeIndex % gradRange, 0, gradRange, scheme.colors[start].B, scheme.colors[end].B) / dimmer; + mColor->R = (uint8_t)fmyRed; + mColor->G = (uint8_t)fmyGrn; + mColor->B = (uint8_t)fmyBlu; +} + +void Ws2812Gradient(uint32_t schemenr) +{ +/* + * This routine courtesy Tony DiCola (Adafruit) + * Display a gradient of colors for the current color scheme. + * Repeat is the number of repetitions of the gradient (pick a multiple of 2 for smooth looping of the gradient). + */ + LedColor c; + + ColorScheme scheme = kSchemes[schemenr]; + if (scheme.count < 2) { return; } + + uint32_t repeat = kWsRepeat[Settings->light_width]; // number of scheme.count per ledcount + uint32_t range = (uint32_t)ceil((float)Settings->light_pixels / (float)repeat); + uint32_t gradRange = (uint32_t)ceil((float)range / (float)(scheme.count - 1)); + uint32_t speed = ((Settings->light_speed * 2) -1) * (STATES / 10); + uint32_t offset = speed > 0 ? Light.strip_timer_counter / speed : 0; + + LedColor oldColor, currentColor; + Ws2812GradientColor(schemenr, &oldColor, range, gradRange, offset); + currentColor = oldColor; + speed = speed ? speed : 1; // should never happen, just avoid div0 + for (uint32_t i = 0; i < Settings->light_pixels; i++) { + if (kWsRepeat[Settings->light_width] > 1) { + Ws2812GradientColor(schemenr, ¤tColor, range, gradRange, i + offset + 1); + } + // Blend old and current color based on time for smooth movement. + c.R = wsmap(Light.strip_timer_counter % speed, 0, speed, oldColor.R, currentColor.R); + c.G = wsmap(Light.strip_timer_counter % speed, 0, speed, oldColor.G, currentColor.G); + c.B = wsmap(Light.strip_timer_counter % speed, 0, speed, oldColor.B, currentColor.B); + strip->SetPixelColor(i, c.C); + oldColor = currentColor; + } + Ws2812StripShow(); +} + +void Ws2812Bars(uint32_t schemenr) +{ +/* + * This routine courtesy Tony DiCola (Adafruit) + * Display solid bars of color for the current color scheme. + * Width is the width of each bar in pixels/lights. + */ + LedColor c; + + ColorScheme scheme = kSchemes[schemenr]; + + uint32_t maxSize = Settings->light_pixels / scheme.count; + if (kWidth[Settings->light_width] > maxSize) { maxSize = 0; } + + uint32_t speed = ((Settings->light_speed * 2) -1) * (STATES / 10); + uint32_t offset = (speed > 0) ? Light.strip_timer_counter / speed : 0; + + LedColor mcolor[scheme.count]; + memcpy(mcolor, scheme.colors, sizeof(mcolor)); + float dimmer = 100 / (float)Settings->light_dimmer; + for (uint32_t i = 0; i < scheme.count; i++) { + float fmyRed = (float)mcolor[i].R / dimmer; + float fmyGrn = (float)mcolor[i].G / dimmer; + float fmyBlu = (float)mcolor[i].B / dimmer; + mcolor[i].R = (uint8_t)fmyRed; + mcolor[i].G = (uint8_t)fmyGrn; + mcolor[i].B = (uint8_t)fmyBlu; + } + uint32_t colorIndex = offset % scheme.count; + for (uint32_t i = 0; i < Settings->light_pixels; i++) { + if (maxSize) { colorIndex = ((i + offset) % (scheme.count * kWidth[Settings->light_width])) / kWidth[Settings->light_width]; } + c.R = mcolor[colorIndex].R; + c.G = mcolor[colorIndex].G; + c.B = mcolor[colorIndex].B; + strip->SetPixelColor(i, c.C); + } + Ws2812StripShow(); +} + +void Ws2812Steps(uint32_t schemenr) { + LedColor c; + + ColorScheme scheme = kSchemes[schemenr]; + // apply main color if current sheme == kStairs + if (scheme.colors == kStairs) { + // we patch the colors + static LedColor colors_stairs[2] = { + { 0x000000 }, + { .B = Settings->light_color[2], .G = Settings->light_color[1], .R = Settings->light_color[0] } + }; + scheme.colors = colors_stairs; + } + + uint8_t scheme_count = scheme.count; + if (Settings->light_fade) { + scheme_count = Settings->ws_width[WS_HOUR]; // Width4 + } + if (scheme_count < 2) { + scheme_count = 2; + } + + LedColor mcolor[scheme_count]; + + uint8_t color_start = 0; + uint8_t color_end = 1; + if (Settings->light_rotation & 0x01) { + color_start = 1; + color_end = 0; + } + + if (Settings->light_fade) { + // generate gradient (width = Width4) + for (uint32_t i = 1; i < scheme_count - 1; i++) { + mcolor[i].R = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].R, scheme.colors[color_end].R); + mcolor[i].G = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].G, scheme.colors[color_end].G); + mcolor[i].B = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].B, scheme.colors[color_end].B); + } + } else { + memcpy(mcolor, scheme.colors, sizeof(mcolor)); + } + // Repair first & last color in gradient; apply scheme rotation if fade==0 + mcolor[0].R = scheme.colors[color_start].R; + mcolor[0].G = scheme.colors[color_start].G; + mcolor[0].B = scheme.colors[color_start].B; + mcolor[scheme_count-1].R = scheme.colors[color_end].R; + mcolor[scheme_count-1].G = scheme.colors[color_end].G; + mcolor[scheme_count-1].B = scheme.colors[color_end].B; + + // Adjust to dimmer value + float dimmer = 100 / (float)Settings->light_dimmer; + for (uint32_t i = 0; i < scheme_count; i++) { + float fmyRed = (float)mcolor[i].R / dimmer; + float fmyGrn = (float)mcolor[i].G / dimmer; + float fmyBlu = (float)mcolor[i].B / dimmer; + mcolor[i].R = (uint8_t)fmyRed; + mcolor[i].G = (uint8_t)fmyGrn; + mcolor[i].B = (uint8_t)fmyBlu; + } + + uint32_t speed = Settings->light_speed; + int32_t current_position = Light.strip_timer_counter / speed; + + //all pixels are shown already | rotation change will not change current state + if (current_position > Settings->light_pixels / Settings->light_step_pixels + scheme_count ) { + return; + } + + int32_t colorIndex; + int32_t step_nr; + + for (uint32_t i = 0; i < Settings->light_pixels; i++) { + step_nr = i / Settings->light_step_pixels; + colorIndex = current_position - step_nr; + if (colorIndex < 0) { colorIndex = 0; } + if (colorIndex > scheme_count - 1) { colorIndex = scheme_count - 1; } + c.R = mcolor[colorIndex].R; + c.G = mcolor[colorIndex].G; + c.B = mcolor[colorIndex].B; + // Adjust the scheme rotation + if (Settings->light_rotation & 0x02) { + strip->SetPixelColor(Settings->light_pixels - i - 1, c.C); + } else { + strip->SetPixelColor(i, c.C); + } + } + Ws2812StripShow(); +} + +#ifdef USE_NETWORK_LIGHT_SCHEMES +void Ws2812DDP(void) +{ + LedColor c = {0}; + + // Can't be trying to initialize UDP too early. + if (TasmotaGlobal.restart_flag || TasmotaGlobal.global_state.network_down) return; + + // Start DDP listener, if fail, just set last ddp_color + if (!ddp_udp_up) { + if (!ddp_udp.begin(4048)) return; + ddp_udp_up = 1; + AddLog(LOG_LEVEL_DEBUG_MORE, "DDP: UDP Listener Started: WS2812 Scheme"); + } + + // Get the DDP payload over UDP + std::vector payload; + while (uint16_t packet_size = ddp_udp.parsePacket()) { + payload.resize(packet_size); + if (!ddp_udp.read(&payload[0], payload.size())) { + continue; + } + } + + // No verification checks performed against packet besides length + if (payload.size() > (9+3*Settings->light_pixels)) { + for (uint32_t i = 0; i < Settings->light_pixels; i++) { + c.R = payload[10+3*i]; + c.G = payload[11+3*i]; + c.B = payload[12+3*i]; + strip->SetPixelColor(i, c.C); + } + Ws2812StripShow(); + } +} +#endif // USE_NETWORK_LIGHT_SCHEMES + +void Ws2812Clear(bool display = true); +void Ws2812Clear(bool display) +{ + strip->ClearTo(0); + if (display) { + Ws2812LibStripShow(); + Ws2812.show_next = 1; + } +} + +void Ws2812SetColor(uint32_t led, uint8_t red, uint8_t green, uint8_t blue, uint8_t white) +{ + LedColor lcolor = {0}; + + lcolor.R = red; + lcolor.G = green; + lcolor.B = blue; + if (led) { + strip->SetPixelColor(led -1, lcolor.C); // Led 1 is strip Led 0 -> substract offset 1 + } else { +// strip->ClearTo(lcolor); // Set WS2812_MAX_LEDS pixels + for (uint32_t i = 0; i < Settings->light_pixels; i++) { + strip->SetPixelColor(i, lcolor.C); + } + } + + if (!Ws2812.suspend_update) { + Ws2812LibStripShow(); + Ws2812.show_next = 1; + } +} + +char* Ws2812GetColor(uint32_t led, char* scolor) +{ + uint8_t sl_ledcolor[4]; + + LedColor lcolor; + lcolor.C = strip->GetPixelColor(led -1); + sl_ledcolor[0] = lcolor.R; + sl_ledcolor[1] = lcolor.G; + sl_ledcolor[2] = lcolor.B; + sl_ledcolor[3] = lcolor.W; + scolor[0] = '\0'; + for (uint32_t i = 0; i < Light.subtype; i++) { + if (Settings->flag.decimal_text) { // SetOption17 - Switch between decimal or hexadecimal output (0 = hexadecimal, 1 = decimal) + snprintf_P(scolor, 25, PSTR("%s%s%d"), scolor, (i > 0) ? "," : "", sl_ledcolor[i]); + } else { + snprintf_P(scolor, 25, PSTR("%s%02X"), scolor, sl_ledcolor[i]); + } + } + return scolor; +} + +/*********************************************************************************************\ + * Public - used by scripter only +\*********************************************************************************************/ + +void Ws2812ForceSuspend (void) +{ + Ws2812.suspend_update = true; +} + +void Ws2812ForceUpdate (void) +{ + Ws2812.suspend_update = false; + Ws2812LibStripShow(); + Ws2812.show_next = 1; +} + +/********************************************************************************************/ + +bool Ws2812SetChannels(void) +{ + uint8_t *cur_col = (uint8_t*)XdrvMailbox.data; + + Ws2812SetColor(0, cur_col[0], cur_col[1], cur_col[2], cur_col[3]); + + return true; +} + +void Ws2812ShowScheme(void) +{ + uint32_t scheme = Settings->light_scheme - Ws2812.scheme_offset; + +#ifdef USE_NETWORK_LIGHT_SCHEMES + if ((scheme != 10) && (ddp_udp_up)) { + ddp_udp.stop(); + ddp_udp_up = 0; + AddLog(LOG_LEVEL_DEBUG_MORE, "DDP: UDP Stopped: WS2812 Scheme not DDP"); + } +#endif + switch (scheme) { + case 0: // Clock + if ((1 == TasmotaGlobal.state_250mS) || (Ws2812.show_next)) { + Ws2812Clock(); + Ws2812.show_next = 0; + } + break; + case 9: // Clear + if (Settings->light_scheme != Light.last_scheme) { + Ws2812Clear(); + } + break; +#ifdef USE_NETWORK_LIGHT_SCHEMES + case 10: + Ws2812DDP(); + break; +#endif // USE_NETWORK_LIGHT_SCHEMES + default: + if(Settings->light_step_pixels > 0){ + Ws2812Steps(scheme -1); + } else { + if (1 == Settings->light_fade) { + Ws2812Gradient(scheme -1); + } else { + Ws2812Bars(scheme -1); + } + } + Ws2812.show_next = 1; + break; + } +} + +bool Ws2812InitStrip(void) +{ + if (strip != nullptr) { + return true; + } + + if (PinUsed(GPIO_WS2812)) { // RGB led + int32_t gpio = Pin(GPIO_WS2812); + TasmotaLEDPusher * pusher = TasmotaLEDPusher::Create(kTasLed_Hardware, gpio); + if (pusher == nullptr) { + AddLog(LOG_LEVEL_ERROR, "LED: No hardware supported"); + return false; + } + strip = new TasmotaLED(kTasLed_Type, Settings->light_pixels); + strip->SetPusher(pusher); + strip->Begin(); + + Ws2812Clear(); + return true; + } + return false; +} + +void Ws2812ModuleSelected(void) +{ + if (Ws2812InitStrip()) { + Ws2812.scheme_offset = Light.max_scheme +1; + Light.max_scheme += WS2812_SCHEMES; + +#ifdef USE_NETWORK_LIGHT_SCHEMES + Light.max_scheme++; +#endif + +#if (USE_WS2812_CTYPE > NEO_3LED) + TasmotaGlobal.light_type = LT_RGBW; +#else + TasmotaGlobal.light_type = LT_RGB; +#endif + TasmotaGlobal.light_driver = XLGT_01; + } +} + +#ifdef ESP32 +#ifdef USE_BERRY +/********************************************************************************************/ +// Callbacks for Berry driver +// +// Since we dont' want to export all the template stuff, we need to encapsulate the calls +// in plain functions +// +void *Ws2812GetStrip(void) { + return strip; +} + +void Ws2812Begin(void) { + if (strip) { strip->Begin(); } +} + +void Ws2812Show(void) { + if (strip) { strip->Show(); } +} + +uint32_t Ws2812PixelsSize(void) { + if (strip) { return strip->PixelCount(); } + return 0; +} + +bool Ws2812CanShow(void) { + if (strip) { return strip->CanShow(); } + return false; +} + +bool Ws2812IsDirty(void) { + if (strip) { return strip->IsDirty(); } + return false; +} + +void Ws2812Dirty(void) { + if (strip) { strip->Dirty(); } +} + +uint8_t * Ws2812Pixels(void) { + if (strip) { return strip->Pixels(); } + return nullptr; +} + +size_t Ws2812PixelSize(void) { + if (strip) { return strip->PixelSize(); } + return 0; +} + +size_t Ws2812PixelCount(void) { + if (strip) { return strip->PixelCount(); } + return 0; +} + +void Ws2812ClearTo(uint8_t r, uint8_t g, uint8_t b, uint8_t w, int32_t from, int32_t to) { + LedColor lcolor; + lcolor.W = w; + lcolor.R = r; + lcolor.G = g; + lcolor.B = b; + if (strip) { + if (from < 0) { + strip->ClearTo(lcolor.C); + } else { + strip->ClearTo(lcolor.C, from, to); + } + } +} + +void Ws2812SetPixelColor(uint32_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t w) +{ + LedColor lcolor; + lcolor.W = w; + lcolor.R = r; + lcolor.G = g; + lcolor.B = b; + if (strip) { + strip->SetPixelColor(idx, lcolor.C); + } +} + +uint32_t Ws2812GetPixelColor(uint32_t idx) { + LedColor lcolor; + if (strip) { + lcolor.C = strip->GetPixelColor(idx); + return lcolor.C; // already encoded as WWRRGGBB + // return (lcolor.W << 24) | (lcolor.R << 16) | (lcolor.G << 8) | lcolor.B; + } + return 0; +} + +#endif // ESP32 +#endif // USE_BERRY + +/********************************************************************************************/ + +void CmndLed(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Settings->light_pixels)) { + if (XdrvMailbox.data_len > 0) { + char *p; + uint16_t idx = XdrvMailbox.index; + Ws2812ForceSuspend(); + for (char *color = strtok_r(XdrvMailbox.data, " ", &p); color; color = strtok_r(nullptr, " ", &p)) { + if (LightColorEntry(color, strlen(color))) { + Ws2812SetColor(idx, Light.entry_color[0], Light.entry_color[1], Light.entry_color[2], Light.entry_color[3]); + idx++; + if (idx > Settings->light_pixels) { break; } + } else { + break; + } + } + Ws2812ForceUpdate(); + } + char scolor[LIGHT_COLOR_SIZE]; + ResponseCmndIdxChar(Ws2812GetColor(XdrvMailbox.index, scolor)); + } +} + +void CmndPixels(void) +{ + if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= WS2812_MAX_LEDS)) { +/* + Settings->light_pixels = XdrvMailbox.payload; + Settings->light_rotation = 0; + Ws2812ReinitStrip(); -- does not work with latest NeoPixelBus driver + Light.update = true; +*/ + Ws2812Clear(); // Clear all known pixels + Settings->light_pixels = XdrvMailbox.payload; + Settings->light_rotation = 0; + TasmotaGlobal.restart_flag = 2; // reboot instead + } + ResponseCmndNumber(Settings->light_pixels); +} + +void CmndStepPixels(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) { + Settings->light_step_pixels = (XdrvMailbox.payload > WS2812_MAX_LEDS) ? WS2812_MAX_LEDS : XdrvMailbox.payload; + // Ws2812ReinitStrip(); -- not sure it's actually needed + Light.update = true; + } + ResponseCmndNumber(Settings->light_step_pixels); +} + + +void CmndRotation(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < Settings->light_pixels)) { + Settings->light_rotation = XdrvMailbox.payload; + } + ResponseCmndNumber(Settings->light_rotation); +} + +void CmndWidth(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) { + if (1 == XdrvMailbox.index) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 4)) { + Settings->light_width = XdrvMailbox.payload; + } + ResponseCmndNumber(Settings->light_width); + } else { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32)) { + Settings->ws_width[XdrvMailbox.index -2] = XdrvMailbox.payload; + } + ResponseCmndIdxNumber(Settings->ws_width[XdrvMailbox.index -2]); + } + } +} + +/*********************************************************************************************\ + * Internal calls for ArtNet +\*********************************************************************************************/ +// check is the Neopixel strip is configured +bool Ws2812StripConfigured(void) { + return strip != nullptr; +} +size_t Ws2812StripGetPixelSize(void) { + return strip->PixelSize(); +} +// return true if strip was dirty and an actual refresh was triggered +bool Ws2812StripRefresh(void) { + if (strip->IsDirty()) { + Ws2812LibStripShow(); + return true; + } else { + return false; + } +} +void Ws2812CopyPixels(const uint8_t *buf, size_t len, size_t offset_in_matrix) { + uint8_t *pixels = strip->Pixels(); + memmove(&pixels[offset_in_matrix], buf, len); + strip->Dirty(); +} + + + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xlgt01(uint32_t function) +{ + bool result = false; + + switch (function) { + case FUNC_SET_CHANNELS: + result = Ws2812SetChannels(); + break; + case FUNC_SET_SCHEME: + Ws2812ShowScheme(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kWs2812Commands, Ws2812Command); + break; + case FUNC_MODULE_INIT: + Ws2812ModuleSelected(); + break; + } + return result; +} + +#endif // USE_WS2812 +#endif // USE_LIGHT +#endif // ESP32 \ No newline at end of file From 3316bc5e70229a99c6f54e7dddae6c9c219efb4d Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Fri, 29 Nov 2024 09:59:18 +0100 Subject: [PATCH 170/205] [Shutter] Fix PowerON (#22548) * [Shutter] Fix PowerON * [Shutter] Fix 2 PowerON * [Shutter] Fix 3 PowerON Integrate only when USE_SHUTTER is defined * @SteWers [Shutter] Fix 4 PowerON Fix compile error --- tasmota/tasmota_support/support_tasmota.ino | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino index 90a171787..d8cceedc4 100644 --- a/tasmota/tasmota_support/support_tasmota.ino +++ b/tasmota/tasmota_support/support_tasmota.ino @@ -466,7 +466,11 @@ void SetPowerOnState(void) for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) { #ifdef ESP8266 if (!Settings->flag3.no_power_feedback && // SetOption63 - Don't scan relay power state at restart - #5594 and #5663 - !TasmotaGlobal.power_on_delay) { // SetOption47 - Delay switching relays to reduce power surge at power on + !TasmotaGlobal.power_on_delay // SetOption47 - Delay switching relays to reduce power surge at power on +#ifdef USE_SHUTTER + && !Settings->flag3.shutter_mode // SetOption80 - Enable shutter support +#endif // USE_SHUTTER + ) { if ((port < MAX_RELAYS) && PinUsed(GPIO_REL1, port)) { if (bitRead(TasmotaGlobal.rel_bistable, port)) { port++; // Skip both bistable relays as always 0 From f176ede65d023000bb80e93b9a837a796c4241cc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 29 Nov 2024 16:16:32 +0100 Subject: [PATCH 171/205] Update changelogs --- CHANGELOG.md | 5 +++-- RELEASENOTES.md | 3 +++ tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino | 7 +++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35534baa8..4270d4838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,14 +11,14 @@ All notable changes to this project will be documented in this file. - ESP32 Hybrid compile take custom boards settings in account (#22542) ### Breaking Changed -- ArtNet on ESP32 switches from GRB to RGB encoding +- ESP32 ArtNet switches from GRB to RGB encoding (#22556) ### Changed - ESP32 max number of supported switches/buttons/relays from 28 to 32 - ESP32 max number of interlocks from 14 to 16 - ESP32 Platform from 2024.11.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.241030 to v3.1.0.241117 and IDF to 5.3.1.241024 (#22504) - Prevent active BLE operations with unencrypted MI-format beacons (#22453) -- Replace NeoPixelBus with TasmotaLED on ESP32x +- ESP32 replaced NeoPixelBus with TasmotaLED (#22556) ### Fixed - ESP32 upgrade by file upload response based on file size (#22500) @@ -26,6 +26,7 @@ All notable changes to this project will be documented in this file. - Use HTML escape on File System Edit File load (#22492) - Magic switch applying masking window to any power change (#22535) - Shift595 output offsets and restart relay toggles +- Shutter wrong power ON state (#22548) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ca9c3883b..526d1a88d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -147,10 +147,12 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - HASPmota `haspmota.get_pages()` to get the sorted list of pages [#22358](https://github.com/arendst/Tasmota/issues/22358) ### Breaking Changed +- ESP32 ArtNet switches from GRB to RGB encoding [#22556](https://github.com/arendst/Tasmota/issues/22556) ### Changed - ESP32 Platform from 2024.09.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241117 and IDF to 5.3.1.241024 [#22504](https://github.com/arendst/Tasmota/issues/22504) - ESP32 LVGL library from v9.2.0 to v9.2.2 [#22385](https://github.com/arendst/Tasmota/issues/22385) +- ESP32 replaced NeoPixelBus with TasmotaLED [#22556](https://github.com/arendst/Tasmota/issues/22556) - Redesign GUI adding feedback to buttons, shutters and lights - Use command `WebButton1` to change GUI shutter 1 name - Unit (k)VAr(h) to (k)var(h) [#22435](https://github.com/arendst/Tasmota/issues/22435) @@ -173,6 +175,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Use HTML escape on File System Edit File load [#22492](https://github.com/arendst/Tasmota/issues/22492) - Prevent crashing when `display.ini` is missing end `#` [#22471](https://github.com/arendst/Tasmota/issues/22471) - Magic switch applying masking window to any power change [#22535](https://github.com/arendst/Tasmota/issues/22535) +- Shutter wrong power ON state [#22548](https://github.com/arendst/Tasmota/issues/22548) - Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) - Mitsubishi Electric HVAC Standby Stage for MiElHVAC [#22430](https://github.com/arendst/Tasmota/issues/22430) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino index 26f5f61ec..31f15d109 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino @@ -33,14 +33,17 @@ * {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"} * {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"} * {"NAME":"Shelly Pro 4PM","GPIO":[0,6210,0,6214,9568,0,0,0,0,0,9569,0,768,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,736,704,3461,0,4736,0,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"} - * + * {"NAME":"Shelly 2PM Gen3","GPIO":[9472,3458,576,225,4736,224,640,608,1,1,193,0,0,0,0,0,0,0,192,32,1,1],"FLAG":0,"BASE":1,"CMND":"ADCGPIO4 10000,10000,4000"} + * * Based on datasheet from https://www.analog.com/en/products/ade7953.html * * Model differences: * Function Model1 Model2 Model3 Model4 Model5 Model6 Remark * ------------------------------ ------- ------- ------- ------ ------ ------ ------------------------------------------------- - * Shelly 2.5 EM Plus2PM Pro1PM Pro2PM Pro4PM + * Shelly 2.5 EM Plus2PM Pro1PM Pro2PM Pro4PM Shelly hardware + * 2PMGen3 * Processor ESP8266 ESP8266 ESP32 ESP32 ESP32 ESP32 + * ESP32C3 Shelly Gen3 * Interface I2C I2C I2C SPI SPI SPI Interface type used * Number of inputs 2 2 2 1 2 4 Count of ADE9753 inputs used * Number of ADE9753 chips 1 1 1 1 2 2 Count of ADE9753 chips From 038e62b72cc11da55c13b66f211c531070f98460 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 29 Nov 2024 17:00:31 +0100 Subject: [PATCH 172/205] Small shutter refactors --- .../xdrv_27_esp32_shutter.ino | 143 +++++++++--------- .../tasmota_xdrv_driver/xdrv_27_shutter.ino | 134 ++++++++-------- 2 files changed, 143 insertions(+), 134 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index 2be8c6f9d..539925152 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -126,7 +126,10 @@ const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|" D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_SETOPEN "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|" D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS "|" D_CMND_SHUTTER_STOPOPEN "|" D_CMND_SHUTTER_STOPCLOSE "|" D_CMND_SHUTTER_STOPTOGGLE "|" D_CMND_SHUTTER_STOPTOGGLEDIR "|" D_CMND_SHUTTER_STOPPOSITION "|" D_CMND_SHUTTER_INCDEC "|" - D_CMND_SHUTTER_UNITTEST "|" D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|" D_CMND_SHUTTER_TILTINCDEC "|" D_CMND_SHUTTER_MOTORSTOP "|" D_CMND_SHUTTER_SETUP "|" +#ifdef SHUTTER_UNITTEST + D_CMND_SHUTTER_UNITTEST "|" +#endif // SHUTTER_UNITTEST + D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|" D_CMND_SHUTTER_TILTINCDEC "|" D_CMND_SHUTTER_MOTORSTOP "|" D_CMND_SHUTTER_SETUP "|" D_CMD_SHUTTER_EXTRASTOPRELAY; void (* const ShutterCommand[])(void) PROGMEM = { @@ -135,7 +138,10 @@ void (* const ShutterCommand[])(void) PROGMEM = { &CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterSetOpen, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay, &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock, &CmndShutterEnableEndStopTime, &CmndShutterInvertWebButtons, &CmndShutterStopOpen, &CmndShutterStopClose, &CmndShutterStopToggle, &CmndShutterStopToggleDir, &CmndShutterStopPosition, &CmndShutterIncDec, - &CmndShutterUnitTest,&CmndShutterTiltConfig,&CmndShutterSetTilt,&CmndShutterTiltIncDec,&CmndShutterMotorStop,&CmndShutterSetup,&CmndShutterExtraStopPulseRelay +#ifdef SHUTTER_UNITTEST + &CmndShutterUnitTest, +#endif // SHUTTER_UNITTEST + &CmndShutterTiltConfig, &CmndShutterSetTilt, &CmndShutterTiltIncDec, &CmndShutterMotorStop, &CmndShutterSetup, &CmndShutterExtraStopPulseRelay }; const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"Direction\":%d,\"Target\":%d,\"Tilt\":%d}"; @@ -2268,6 +2274,62 @@ void CmndShutterToggleDir(void) ShutterToggle(true); } +#ifdef SHUTTER_UNITTEST +void CmndShutterUnitTest(void) { + int16_t input_percent[10] = {-5,0,10,26,35,55,80,99,100,105}; + int16_t output_percent[10] = {0,0,10,26,35,55,80,99,100,100}; + uint32_t result_percent[2][2][10] = {{{0,0,24000,62400,84000,132000,192000,237600,240000,240000}, + {0,0,360000,936000,1260000,1980000,2880000,3564000,3600000,3600000}}, + {{0,0,76296,100000,113333,174299,205795,237983,240000,240000}, + {0,0,1144444,1500000,1700000,2614488,3086929,3569748,3600000,3600000}}}; + + uint32_t result = 0; + char svalue[50]; // Command and number parameter + ShutterSettings.shuttercoeff[0][0] = 0; + for (uint8_t i=0; i<2 ; i++){ + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 12); + ExecuteCommand(svalue, SRC_SHUTTER); + ShutterInit(); + for (uint8_t j=0; j<2 ; j++){ + for (uint8_t k=0; k<10 ; k++){ + result += (result_percent[i][j][k] == ShutterPercentToRealPosition(input_percent[k] , 0) ? 0 : 1); + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition error %d: %d <-> %d"),result, ShutterPercentToRealPosition(input_percent[k] , 0), result_percent[i][j][k]); + } + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 180); + ExecuteCommand(svalue, SRC_SHUTTER); + } + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_CLIBRATION "%d %s"), 1, "15 83 105 185 210"); + ExecuteCommand(svalue, SRC_SHUTTER); + } + if (!result){ + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition: PASS")); + } else { + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition: FAIL")); + } + ShutterSettings.shuttercoeff[0][0] = 0; + for (uint8_t i=0; i<2 ; i++){ + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 12); + ExecuteCommand(svalue, SRC_SHUTTER); + ShutterInit(); + for (uint8_t j=0; j<2 ; j++){ + for (uint8_t k=0; k<10 ; k++){ + result += (output_percent[k] == ShutterRealToPercentPosition(result_percent[i][j][k] , 0) ? 0 : 1); + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition error %d: %d <-> %d"),result, ShutterRealToPercentPosition(result_percent[i][j][k] , 0), output_percent[k]); + } + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 180); + ExecuteCommand(svalue, SRC_SHUTTER); + } + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_CLIBRATION "%d %s"), 1, "15 83 105 185 210"); + ExecuteCommand(svalue, SRC_SHUTTER); + } + if (!result){ + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition: PASS")); + } else { + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition: FAIL")); + } +} +#endif // SHUTTER_UNITTEST + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -2285,6 +2347,13 @@ bool Xdrv27(uint32_t function) char stemp1[10]; power_t save_powermatrix; switch (function) { + case FUNC_EVERY_50_MSECOND: + ShutterUpdatePosition(); + break; + case FUNC_EVERY_SECOND: + //case FUNC_EVERY_250_MSECOND: + ShutterReportPosition(false, MAX_SHUTTERS_ESP32); + break; case FUNC_RESTORE_SETTINGS: result = ShutterSettingsRestore(); break; @@ -2293,18 +2362,13 @@ bool Xdrv27(uint32_t function) break; case FUNC_PRE_INIT: ShutterSettingsLoad(0); + break; + case FUNC_INIT: ShutterInit(); break; case FUNC_RESET_SETTINGS: ShutterSettingsLoad(1); break; - case FUNC_EVERY_50_MSECOND: - ShutterUpdatePosition(); - break; - case FUNC_EVERY_SECOND: - //case FUNC_EVERY_250_MSECOND: - ShutterReportPosition(false, MAX_SHUTTERS_ESP32); - break; case FUNC_COMMAND: for (uint8_t i = counter; i <= counterend; i++) { XdrvMailbox.index = i; @@ -2391,64 +2455,5 @@ bool Xdrv27(uint32_t function) return result; } -#endif //USE_SHUTTER - -#ifdef SHUTTER_UNITTEST -void CmndShutterUnitTest(void) { - int16_t input_percent[10] = {-5,0,10,26,35,55,80,99,100,105}; - int16_t output_percent[10] = {0,0,10,26,35,55,80,99,100,100}; - uint32_t result_percent[2][2][10] = {{{0,0,24000,62400,84000,132000,192000,237600,240000,240000}, - {0,0,360000,936000,1260000,1980000,2880000,3564000,3600000,3600000}}, - {{0,0,76296,100000,113333,174299,205795,237983,240000,240000}, - {0,0,1144444,1500000,1700000,2614488,3086929,3569748,3600000,3600000}}}; - - uint32_t result = 0; - char svalue[50]; // Command and number parameter - ShutterSettings.shuttercoeff[0][0] = 0; - for (uint8_t i=0; i<2 ; i++){ - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 12); - ExecuteCommand(svalue, SRC_SHUTTER); - ShutterInit(); - for (uint8_t j=0; j<2 ; j++){ - for (uint8_t k=0; k<10 ; k++){ - result += (result_percent[i][j][k] == ShutterPercentToRealPosition(input_percent[k] , 0) ? 0 : 1); - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition error %d: %d <-> %d"),result, ShutterPercentToRealPosition(input_percent[k] , 0), result_percent[i][j][k]); - } - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 180); - ExecuteCommand(svalue, SRC_SHUTTER); - } - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_CLIBRATION "%d %s"), 1, "15 83 105 185 210"); - ExecuteCommand(svalue, SRC_SHUTTER); - } - if (!result){ - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition: PASS")); - } else { - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition: FAIL")); - } - ShutterSettings.shuttercoeff[0][0] = 0; - for (uint8_t i=0; i<2 ; i++){ - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 12); - ExecuteCommand(svalue, SRC_SHUTTER); - ShutterInit(); - for (uint8_t j=0; j<2 ; j++){ - for (uint8_t k=0; k<10 ; k++){ - result += (output_percent[k] == ShutterRealToPercentPosition(result_percent[i][j][k] , 0) ? 0 : 1); - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition error %d: %d <-> %d"),result, ShutterRealToPercentPosition(result_percent[i][j][k] , 0), output_percent[k]); - } - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 180); - ExecuteCommand(svalue, SRC_SHUTTER); - } - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_CLIBRATION "%d %s"), 1, "15 83 105 185 210"); - ExecuteCommand(svalue, SRC_SHUTTER); - } - if (!result){ - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition: PASS")); - } else { - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition: FAIL")); - } -} -#else -void CmndShutterUnitTest(void) {} -#endif // SHUTTER_UNITTEST - +#endif // USE_SHUTTER #endif // ESP32 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index da7c7a138..7bc096a4b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -19,6 +19,7 @@ #ifdef ESP8266 #ifdef USE_SHUTTER +//#if defined(USE_SHUTTER) && !defined(USE_UFILESYS) /*********************************************************************************************\ * Shutter or Blind support using two consecutive relays \*********************************************************************************************/ @@ -65,7 +66,10 @@ const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|" D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_SETOPEN "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|" D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS "|" D_CMND_SHUTTER_STOPOPEN "|" D_CMND_SHUTTER_STOPCLOSE "|" D_CMND_SHUTTER_STOPTOGGLE "|" D_CMND_SHUTTER_STOPTOGGLEDIR "|" D_CMND_SHUTTER_STOPPOSITION "|" D_CMND_SHUTTER_INCDEC "|" - D_CMND_SHUTTER_UNITTEST "|" D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|" D_CMND_SHUTTER_TILTINCDEC "|" D_CMND_SHUTTER_MOTORSTOP; +#ifdef SHUTTER_UNITTEST + D_CMND_SHUTTER_UNITTEST "|" +#endif // SHUTTER_UNITTEST + D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|" D_CMND_SHUTTER_TILTINCDEC "|" D_CMND_SHUTTER_MOTORSTOP; void (* const ShutterCommand[])(void) PROGMEM = { &CmndShutterOpen, &CmndShutterClose, &CmndShutterToggle, &CmndShutterToggleDir, &CmndShutterStop, &CmndShutterPosition, @@ -73,7 +77,10 @@ void (* const ShutterCommand[])(void) PROGMEM = { &CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterSetOpen, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay, &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock, &CmndShutterEnableEndStopTime, &CmndShutterInvertWebButtons, &CmndShutterStopOpen, &CmndShutterStopClose, &CmndShutterStopToggle, &CmndShutterStopToggleDir, &CmndShutterStopPosition, &CmndShutterIncDec, - &CmndShutterUnitTest,&CmndShutterTiltConfig,&CmndShutterSetTilt,&CmndShutterTiltIncDec,&CmndShutterMotorStop}; +#ifdef SHUTTER_UNITTEST + &CmndShutterUnitTest, +#endif // SHUTTER_UNITTEST + &CmndShutterTiltConfig, &CmndShutterSetTilt, &CmndShutterTiltIncDec, &CmndShutterMotorStop}; const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"Direction\":%d,\"Target\":%d,\"Tilt\":%d}"; const char JSON_SHUTTER_BUTTON[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Button%d\":%d}"; @@ -1875,6 +1882,62 @@ void CmndShutterMotorStop(void) } } +#ifdef SHUTTER_UNITTEST +void CmndShutterUnitTest(void) { + int16_t input_percent[10] = {-5,0,10,26,35,55,80,99,100,105}; + int16_t output_percent[10] = {0,0,10,26,35,55,80,99,100,100}; + uint32_t result_percent[2][2][10] = {{{0,0,24000,62400,84000,132000,192000,237600,240000,240000}, + {0,0,360000,936000,1260000,1980000,2880000,3564000,3600000,3600000}}, + {{0,0,76296,100000,113333,174299,205795,237983,240000,240000}, + {0,0,1144444,1500000,1700000,2614488,3086929,3569748,3600000,3600000}}}; + + uint32_t result = 0; + char svalue[50]; // Command and number parameter + Settings->shuttercoeff[0][0] = 0; + for (uint8_t i=0; i<2 ; i++){ + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 12); + ExecuteCommand(svalue, SRC_SHUTTER); + ShutterInit(); + for (uint8_t j=0; j<2 ; j++){ + for (uint8_t k=0; k<10 ; k++){ + result += (result_percent[i][j][k] == ShutterPercentToRealPosition(input_percent[k] , 0) ? 0 : 1); + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition error %d: %d <-> %d"),result, ShutterPercentToRealPosition(input_percent[k] , 0), result_percent[i][j][k]); + } + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 180); + ExecuteCommand(svalue, SRC_SHUTTER); + } + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_CLIBRATION "%d %s"), 1, "15 83 105 185 210"); + ExecuteCommand(svalue, SRC_SHUTTER); + } + if (!result){ + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition: PASS")); + } else { + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition: FAIL")); + } + Settings->shuttercoeff[0][0] = 0; + for (uint8_t i=0; i<2 ; i++){ + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 12); + ExecuteCommand(svalue, SRC_SHUTTER); + ShutterInit(); + for (uint8_t j=0; j<2 ; j++){ + for (uint8_t k=0; k<10 ; k++){ + result += (output_percent[k] == ShutterRealToPercentPosition(result_percent[i][j][k] , 0) ? 0 : 1); + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition error %d: %d <-> %d"),result, ShutterRealToPercentPosition(result_percent[i][j][k] , 0), output_percent[k]); + } + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 180); + ExecuteCommand(svalue, SRC_SHUTTER); + } + snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_CLIBRATION "%d %s"), 1, "15 83 105 185 210"); + ExecuteCommand(svalue, SRC_SHUTTER); + } + if (!result){ + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition: PASS")); + } else { + AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition: FAIL")); + } +} +#endif // SHUTTER_UNITTEST + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -1892,9 +1955,6 @@ bool Xdrv27(uint32_t function) char stemp1[10]; power_t save_powermatrix; switch (function) { - case FUNC_PRE_INIT: - ShutterInit(); - break; case FUNC_EVERY_50_MSECOND: ShutterUpdatePosition(); break; @@ -1902,6 +1962,9 @@ bool Xdrv27(uint32_t function) //case FUNC_EVERY_250_MSECOND: ShutterReportPosition(false, MAX_SHUTTERS); break; + case FUNC_INIT: + ShutterInit(); + break; case FUNC_COMMAND: for (uint8_t i = counter; i <= counterend; i++) { XdrvMailbox.index = i; @@ -1974,64 +2037,5 @@ bool Xdrv27(uint32_t function) return result; } -#endif //USE_SHUTTER - -#ifdef SHUTTER_UNITTEST -void CmndShutterUnitTest(void) { - int16_t input_percent[10] = {-5,0,10,26,35,55,80,99,100,105}; - int16_t output_percent[10] = {0,0,10,26,35,55,80,99,100,100}; - uint32_t result_percent[2][2][10] = {{{0,0,24000,62400,84000,132000,192000,237600,240000,240000}, - {0,0,360000,936000,1260000,1980000,2880000,3564000,3600000,3600000}}, - {{0,0,76296,100000,113333,174299,205795,237983,240000,240000}, - {0,0,1144444,1500000,1700000,2614488,3086929,3569748,3600000,3600000}}}; - - uint32_t result = 0; - char svalue[50]; // Command and number parameter - Settings->shuttercoeff[0][0] = 0; - for (uint8_t i=0; i<2 ; i++){ - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 12); - ExecuteCommand(svalue, SRC_SHUTTER); - ShutterInit(); - for (uint8_t j=0; j<2 ; j++){ - for (uint8_t k=0; k<10 ; k++){ - result += (result_percent[i][j][k] == ShutterPercentToRealPosition(input_percent[k] , 0) ? 0 : 1); - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition error %d: %d <-> %d"),result, ShutterPercentToRealPosition(input_percent[k] , 0), result_percent[i][j][k]); - } - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 180); - ExecuteCommand(svalue, SRC_SHUTTER); - } - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_CLIBRATION "%d %s"), 1, "15 83 105 185 210"); - ExecuteCommand(svalue, SRC_SHUTTER); - } - if (!result){ - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition: PASS")); - } else { - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterPercentToRealPosition: FAIL")); - } - Settings->shuttercoeff[0][0] = 0; - for (uint8_t i=0; i<2 ; i++){ - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 12); - ExecuteCommand(svalue, SRC_SHUTTER); - ShutterInit(); - for (uint8_t j=0; j<2 ; j++){ - for (uint8_t k=0; k<10 ; k++){ - result += (output_percent[k] == ShutterRealToPercentPosition(result_percent[i][j][k] , 0) ? 0 : 1); - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition error %d: %d <-> %d"),result, ShutterRealToPercentPosition(result_percent[i][j][k] , 0), output_percent[k]); - } - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_OPENTIME "%d %d"), 1, 180); - ExecuteCommand(svalue, SRC_SHUTTER); - } - snprintf_P(svalue, sizeof(svalue), PSTR(D_PRFX_SHUTTER D_CMND_SHUTTER_CLIBRATION "%d %s"), 1, "15 83 105 185 210"); - ExecuteCommand(svalue, SRC_SHUTTER); - } - if (!result){ - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition: PASS")); - } else { - AddLog(LOG_LEVEL_ERROR, PSTR("SHT: ShutterRealToPercentPosition: FAIL")); - } -} -#else -void CmndShutterUnitTest(void) {} -#endif - +#endif // USE_SHUTTER #endif // ESP8266 From a838ec09f8b2c2d4025975e905b1f764fb4f099f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 30 Nov 2024 13:51:47 +0100 Subject: [PATCH 173/205] Minor changes --- tasmota/include/tasmota.h | 2 +- tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index fccfc5b66..a9983cc04 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -40,7 +40,7 @@ const uint32_t POWER_SIZE = 32; // Power (relay) bit count #ifdef ESP8266 const uint8_t MAX_RELAYS = 8; // Max number of relays selectable on GPIO -const uint8_t MAX_INTERLOCKS = 4; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) +const uint8_t MAX_INTERLOCKS = 16; // Max number of interlock groups (up to MAX_INTERLOCKS_SET) const uint8_t MAX_SWITCHES = 8; // Max number of switches selectable on GPIO const uint8_t MAX_KEYS = 8; // Max number of keys or buttons selectable on GPIO #endif // ESP8266 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 80616d21b..3526aec65 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -483,11 +483,7 @@ struct WEB { uint32_t upload_size = 0; uint32_t slider_update_time = 0; int slider[LST_MAX]; -#ifdef ESP8266 - int8_t shutter_slider[MAX_SHUTTERS]; -#else // ESP32 int8_t shutter_slider[16]; // MAX_SHUTTERS_ESP32 -#endif // ESP8266 uint16_t upload_error = 0; uint8_t state = HTTP_OFF; uint8_t upload_file_type; @@ -1283,6 +1279,8 @@ void WebGetDeviceCounts(uint32_t &buttons_non_light, uint32_t &buttons_non_light } } #endif // USE_SHUTTER + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HTP: DP %d, BNL %d, BNLNS %d, SB %08X"), TasmotaGlobal.devices_present, buttons_non_light, buttons_non_light_non_shutter, shutter_button); } #ifdef USE_LIGHT From fbb2c84f293bace0994a4607547aa741bf5c63c5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 30 Nov 2024 16:52:57 +0100 Subject: [PATCH 174/205] Template for Shelly 1PM Gen3 --- tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino index 4d9d1b15f..8dcc7430e 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino @@ -25,13 +25,14 @@ /*********************************************************************************************\ * Support the following Shangai Belling energy sensors: * - * BL0942 - Energy (as in Shelly Plus1PMMini) - * Template {"NAME":"Shelly Plus1PMMini","GPIO":[576,32,0,4736,0,224,3200,8161,0,0,192,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350} - * Template {"NAME":"Shelly PlusPMMini","GPIO":[576,32,0,4736,0,0,3200,8161,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350} + * BL0942 - Energy (as in Shelly Gen3) + * {"NAME":"Shelly 1PM Gen3","GPIO":[0,32,0,4736,224,0,3200,8161,576,1,192,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000"} + * {"NAME":"Shelly Plus1PMMini","GPIO":[576,32,0,4736,0,224,3200,8161,0,0,192,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350} + * {"NAME":"Shelly PlusPMMini","GPIO":[576,32,0,4736,0,0,3200,8161,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350} * Based on datasheet from https://datasheet.lcsc.com/lcsc/2110191830_BL-Shanghai-Belling-BL0942_C2909509.pdf * * 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} + * {"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) From bed14174bc3269551cb54f87d78be9093045c61c Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Sat, 30 Nov 2024 19:01:12 +0100 Subject: [PATCH 175/205] add lp_core to Berry ULP module (#22567) --- lib/libesp32/berry/default/be_modtab.c | 2 +- lib/libesp32/berry_tasmota/src/be_ULP_lib.c | 2 +- .../xdrv_52_3_berry_ulp.ino | 87 ++++++++++--------- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c index f948b7d04..f6a695145 100644 --- a/lib/libesp32/berry/default/be_modtab.c +++ b/lib/libesp32/berry/default/be_modtab.c @@ -178,7 +178,7 @@ BERRY_LOCAL const bntvmodule_t* const be_module_table[] = { &be_native_module(partition_core), &be_native_module(crc), &be_native_module(crypto), -#if defined(USE_BERRY_ULP) && ((CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)) +#if defined(USE_BERRY_ULP) && defined(CONFIG_ULP_COPROC_ENABLED) &be_native_module(ULP), #endif // USE_BERRY_ULP #if defined(USE_BERRY_TF_LITE) diff --git a/lib/libesp32/berry_tasmota/src/be_ULP_lib.c b/lib/libesp32/berry_tasmota/src/be_ULP_lib.c index d133b2241..6e56dffe5 100644 --- a/lib/libesp32/berry_tasmota/src/be_ULP_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_ULP_lib.c @@ -6,7 +6,7 @@ #include "be_constobj.h" #include "be_mapping.h" -#if defined(USE_BERRY_ULP) && (defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)) +#if defined(USE_BERRY_ULP) && defined(CONFIG_ULP_COPROC_ENABLED) extern void be_ULP_run(int32_t entry); BE_FUNC_CTYPE_DECLARE(be_ULP_run, "", "[i]"); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino index 24835b64f..5c17dc13c 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino @@ -21,34 +21,39 @@ #ifdef USE_BERRY_ULP #include -#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +// #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_ULP_COPROC_TYPE_LP_CORE) +#if defined(CONFIG_ULP_COPROC_ENABLED) #if defined(CONFIG_IDF_TARGET_ESP32) #include "esp32/ulp.h" #endif // esp32 -#if ESP_IDF_VERSION_MAJOR < 5 - #if defined(CONFIG_IDF_TARGET_ESP32S2) - #include "esp32s2/ulp.h" - #include "esp32s2/ulp_riscv.h" - #include "esp32s2/ulp_riscv_adc.h" - #endif // s2 - #if defined(CONFIG_IDF_TARGET_ESP32S3) - #include "esp32s3/ulp.h" - #include "esp32s3/ulp_riscv.h" - #include "esp32s3/ulp_riscv_adc.h" - #endif //s3 -#endif // ESP_IDF_VERSION_MAJOR < 5 +// #if ESP_IDF_VERSION_MAJOR < 5 +// #if defined(CONFIG_IDF_TARGET_ESP32S2) +// #include "esp32s2/ulp.h" +// #include "esp32s2/ulp_riscv.h" +// #include "esp32s2/ulp_riscv_adc.h" +// #endif // s2 +// #if defined(CONFIG_IDF_TARGET_ESP32S3) +// #include "esp32s3/ulp.h" +// #include "esp32s3/ulp_riscv.h" +// #include "esp32s3/ulp_riscv_adc.h" +// #endif //s3 +// #endif // ESP_IDF_VERSION_MAJOR < 5 #include "driver/rtc_io.h" #include "driver/gpio.h" -#if ESP_IDF_VERSION_MAJOR >= 5 +// #if ESP_IDF_VERSION_MAJOR >= 5 #include "esp_adc/adc_oneshot.h" #include "ulp_adc.h" - #if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + #if defined(CONFIG_ULP_COPROC_TYPE_RISCV) // S2 or S3 #include "ulp_riscv.h" #endif // defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) -#else - #include "driver/adc.h" -#endif // ESP_IDF_VERSION_MAJOR >= 5 +// #else +// #include "driver/adc.h" +// #endif // ESP_IDF_VERSION_MAJOR >= 5 +#ifdef CONFIG_ULP_COPROC_TYPE_LP_CORE + #include "ulp_lp_core.h" + ulp_lp_core_cfg_t be_ulp_lp_core_cfg; +#endif //CONFIG_ULP_COPROC_TYPE_LP_CORE #include "sdkconfig.h" @@ -60,14 +65,21 @@ extern "C" { void be_ULP_run(int32_t entry) { #if defined(CONFIG_IDF_TARGET_ESP32) ulp_run(entry); // entry point should be at the beginning of program -#else // S2 or S3 +#elif defined(CONFIG_ULP_COPROC_TYPE_RISCV) // S2 or S3 ulp_riscv_run(); +#else // lp_core + int err = ulp_lp_core_run(&be_ulp_lp_core_cfg); #endif } // `ULP.wake_period(period_index:int, period_us:int) -> nil` void be_ULP_wake_up_period(int32_t period_index, int32_t period_us) { +#ifdef CONFIG_ULP_COPROC_TYPE_LP_CORE + be_ulp_lp_core_cfg.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER; + be_ulp_lp_core_cfg.lp_timer_sleep_duration_us = period_us; +#else ulp_set_wakeup_period(period_index, period_us); +#endif //CONFIG_ULP_COPROC_TYPE_LP_CORE } // `ULP.set_mem(position:int, value:int) -> value:int` @@ -102,7 +114,6 @@ extern "C" { // enums: channel 0-7, attenuation 0-3, width 0-3 void be_ULP_adc_config(struct bvm *vm, int32_t channel, int32_t attenuation, int32_t width) { #if defined(CONFIG_IDF_TARGET_ESP32) -#if ESP_IDF_VERSION_MAJOR >= 5 ulp_adc_cfg_t cfg = { .adc_n = ADC_UNIT_1, .channel = (adc_channel_t)channel, @@ -111,20 +122,7 @@ extern "C" { .ulp_mode = ADC_ULP_MODE_FSM, }; esp_err_t err = ulp_adc_init(&cfg); -#else - esp_err_t err = adc1_config_channel_atten((adc1_channel_t)channel, (adc_atten_t)attenuation); - err += adc1_config_width((adc_bits_width_t)width); -#endif // ESP_IDF_VERSION_MAJOR >= 5 - if (err != ESP_OK) { - be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err); - } -#if ESP_IDF_VERSION_MAJOR < 5 - else { - adc1_ulp_enable(); - } -#endif // ESP_IDF_VERSION_MAJOR < 5 -#else // S2 or S3 -#if ESP_IDF_VERSION_MAJOR >= 5 +#elif defined(CONFIG_ULP_COPROC_TYPE_RISCV) // S2 or S3 ulp_adc_cfg_t cfg = { .adc_n = ADC_UNIT_1, .channel = (adc_channel_t)channel, @@ -134,17 +132,18 @@ extern "C" { }; esp_err_t err = ulp_adc_init(&cfg); #else - ulp_riscv_adc_cfg_t cfg = { - .channel = (adc_channel_t)channel, - .atten = (adc_atten_t)attenuation, - .width = (adc_bits_width_t)width - }; - esp_err_t err = ulp_riscv_adc_init(&cfg); -#endif // ESP_IDF_VERSION_MAJOR >= 5 + // esp_err_t err = lp_core_lp_adc_init(ADC_UNIT_1); + // const lp_core_lp_adc_chan_cfg_t config = { + // .atten = (adc_atten_t)attenuation, + // .bitwidth = (adc_bitwidth_t)width, + // }; + // err += lp_core_lp_adc_config_channel(ADC_UNIT_1, (adc_channel_t)channel, &config); + be_raisef(vm, "ulp_adc_config_error", "ULP: not supported before ESP-IDF 5.4"); + esp_err_t err = ESP_FAIL; +#endif if (err != ESP_OK) { be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err); } -#endif } /** @@ -156,8 +155,10 @@ extern "C" { void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size) { #if defined(CONFIG_IDF_TARGET_ESP32) esp_err_t err = ulp_load_binary(0, buf, size / 4); // FSM type only, specific header, size in long words -#else // S2 or S3 +#elif defined(CONFIG_ULP_COPROC_TYPE_RISCV) // S2 or S3 esp_err_t err = ulp_riscv_load_binary(buf, size); // there are no header bytes, just load and hope for a valid binary - size in bytes +#else + esp_err_t err = ulp_lp_core_load_binary(buf,size); // check valid size, size in bytes #endif // defined(CONFIG_IDF_TARGET_ESP32) if (err != ESP_OK) { be_raisef(vm, "ulp_load_error", "ULP: invalid code err=%i", err); From e1fc36361e4ef92d4684e4aed17314889ce796a4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 1 Dec 2024 13:07:37 +0100 Subject: [PATCH 176/205] Update changelogs --- CHANGELOG.md | 5 +++++ RELEASENOTES.md | 1 + 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4270d4838..ae5ecba05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ All notable changes to this project will be documented in this file. - Command `SetOption161 1` to disable display of state text (#22515) - ESP32 new BLE filters by name and minimum RSSI (#22530) - ESP32 Hybrid compile take custom boards settings in account (#22542) +- ESP32 ULP lp_core to Berry ULP module (#22567) +- Shelly 1 Gen3 template {"NAME":"Shelly 1 Gen3","GPIO":[0,0,0,4736,0,224,0,0,1,1,192,0,0,0,0,0,0,0,0,576,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000"} +- Shelly 1PM Gen3 template {"NAME":"Shelly 1PM Gen3","GPIO":[0,32,0,4736,224,0,3200,8161,576,1,192,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000"} +- Shelly 2PM Gen3 template {"NAME":"Shelly 2PM Gen3","GPIO":[9472,3458,576,225,4736,224,640,608,1,1,193,0,0,0,0,0,0,0,192,32,1,1],"FLAG":0,"BASE":1,"CMND":"ADCGPIO4 10000,10000,4000"} ### Breaking Changed - ESP32 ArtNet switches from GRB to RGB encoding (#22556) @@ -58,6 +62,7 @@ All notable changes to this project will be documented in this file. - Support for MS5837 pressure and temperature sensor (#22376) - Berry add I2C read16/write16 supporting Little Endian (#22448) - Berry drivers for PCA9535 (generic and in SenseCAP D1) (#22451) +- Shelly DALI Dimmer Gen3 template {"NAME":"Shelly DALI Dimmer Gen3","GPIO":[34,4736,0,3840,11360,11392,128,129,0,1,576,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1,"CMND":"ADCGPIO1 10000,10000,4000} ### Changed - AHT1X/AHT2X/AHT3X ready for virtual I2C (#22427) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 526d1a88d..67289a9b5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -138,6 +138,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC [#22370](https://github.com/arendst/Tasmota/issues/22370) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) +- ESP32 ULP lp_core to Berry ULP module (#22567)[#22567](https://github.com/arendst/Tasmota/issues/22567) - ESP32 new BLE filters by name and minimum RSSI [#22530](https://github.com/arendst/Tasmota/issues/22530) - ESP32 Hybrid compile take custom boards settings in account [#22542](https://github.com/arendst/Tasmota/issues/22542) - ESP32 MI32 legacy add config operations [#22458](https://github.com/arendst/Tasmota/issues/22458) From 0ea888999723a5009abacea7c04a9ad6707b08cc Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Sun, 1 Dec 2024 13:54:11 +0100 Subject: [PATCH 177/205] [SolaxX1] Energy calculation (#22568) --- .../tasmota_xnrg_energy/xnrg_12_solaxX1.ino | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino index d0f8ad9e9..4b26748eb 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino @@ -32,6 +32,7 @@ // #define SOLAXX1_READCONFIG // enable to read inverters config; disable to save codespace (3k1) +#define SOLAXX1_BUFFERSIZE 256 #define INVERTER_ADDRESS 0x0A #define D_SOLAX_X1 "SolaxX1" @@ -100,6 +101,7 @@ union { struct SOLAXX1_LIVEDATA { int16_t temperature = 0; float energy_today = 0; + float energy_total = 0; float dc1_voltage = 0; float dc2_voltage = 0; float dc1_current = 0; @@ -329,7 +331,7 @@ void solaxX1_SwitchMeterMode(bool MeterMode) { /*********************************************************************************************/ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds - uint8_t DataRead[256] = {0}; + uint8_t DataRead[SOLAXX1_BUFFERSIZE] = {0}; uint8_t TempData[16] = {0}; char TempDataChar[32]; float TempFloat; @@ -399,7 +401,7 @@ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds Energy->frequency[0] = ((DataRead[25] << 8) | DataRead[26]) * 0.01f; // AC Frequency Energy->active_power[0] = ((DataRead[27] << 8) | DataRead[28]); // AC Power //temporal = (float)((DataRead[29] << 8) | DataRead[30]) * 0.1f; // Not Used - Energy->import_active[0] = ((DataRead[31] << 24) | (DataRead[32] << 16) | (DataRead[33] << 8) | DataRead[34]) * 0.1f; // Energy Total + solaxX1.energy_total = ((DataRead[31] << 24) | (DataRead[32] << 16) | (DataRead[33] << 8) | DataRead[34]) * 0.1f; // Energy Total uint32_t runtime_total = (DataRead[35] << 24) | (DataRead[36] << 16) | (DataRead[37] << 8) | DataRead[38]; // Work Time Total if (runtime_total) solaxX1.runtime_total = runtime_total; // Work Time valid solaxX1.runMode = (DataRead[39] << 8) | DataRead[40]; // Work mode @@ -413,7 +415,10 @@ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds solaxX1.errorCode = (DataRead[58] << 24) | (DataRead[57] << 16) | (DataRead[56] << 8) | DataRead[55]; // Error Code solaxX1.dc1_power = solaxX1.dc1_voltage * solaxX1.dc1_current; solaxX1.dc2_power = solaxX1.dc2_voltage * solaxX1.dc2_current; - EnergyUpdateTotal(); // 484.708 kWh + if (Settings->flag3.hardware_energy_total) { // SetOption72 - Enable hardware energy total counter as reference (#6561) + Energy->import_active[0] = solaxX1.energy_total; + EnergyUpdateTotal(); // 484.708 kWh + } DEBUG_SENSOR_LOG(PSTR("SX1: received live data")); return; } // end received "Response for query (live data)" @@ -569,9 +574,16 @@ void solaxX1_CyclicTask(void) { // Every 100/250 milliseconds return; } // end solaxX1_CyclicTask +void solaxX1_EverySecond(void) { + if (Settings->flag3.hardware_energy_total) return; // SetOption72 - Enable hardware energy total counter as reference (#6561) + if (Energy->data_valid[0]) return; + Energy->kWhtoday_delta[0] += Energy->active_power[0] * 1000 / 36; + EnergyUpdateToday(); +} // end solaxX1_EverySecond + void solaxX1_SnsInit(void) { AddLog(LOG_LEVEL_INFO, PSTR("SX1: Init - RX-pin: %d, TX-pin: %d, RTS-pin: %d"), Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), Pin(GPIO_SOLAXX1_RTS)); - solaxX1Serial = new TasmotaSerial(Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), 1, 0, 256); + solaxX1Serial = new TasmotaSerial(Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), 1, 1, SOLAXX1_BUFFERSIZE); if (solaxX1Serial->begin(SOLAXX1_SPEED)) { if (solaxX1Serial->hardwareSerial()) { ClaimSerial(); } #ifdef ESP32 @@ -655,6 +667,10 @@ void solaxX1_Show(uint32_t function) { char pv2_power[33]; dtostrfd(solaxX1.dc2_power, Settings->flag2.wattage_resolution, pv2_power); #endif + char inverter_today[33]; + dtostrfd(solaxX1.energy_today, Settings->flag2.energy_resolution, inverter_today); + char inverter_total[33]; + dtostrfd(solaxX1.energy_total, Settings->flag2.energy_resolution, inverter_total); char status[33]; GetTextIndexed(status, sizeof(status), solaxX1.runMode + 2, kSolaxMode); @@ -702,6 +718,10 @@ void solaxX1_Show(uint32_t function) { WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_PV2_CURRENT, table_align.c_str(), pv2_current, D_UNIT_AMPERE); WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_PV2_POWER, table_align.c_str(), pv2_power, D_UNIT_WATT); #endif + if (!Settings->flag3.hardware_energy_total) { // SetOption72 - Enable hardware energy total counter as reference (#6561) + WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_ENERGY_TODAY, table_align.c_str(), inverter_today, D_UNIT_KILOWATTHOUR); + WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_ENERGY_TOTAL, table_align.c_str(), inverter_total, D_UNIT_KILOWATTHOUR); + } char SXTemperature[16]; dtostrfd(solaxX1.temperature, Settings->flag2.temperature_resolution, SXTemperature); WSContentSend_PD(HTTP_SNS_solaxX1_Num, D_TEMPERATURE, table_align.c_str(), SXTemperature, D_UNIT_DEGREE D_UNIT_CELSIUS); @@ -733,6 +753,9 @@ bool Xnrg12(uint32_t function) { case FUNC_EVERY_250_MSECOND: if (!solaxX1_global.MeterMode) solaxX1_CyclicTask(); break; + case FUNC_EVERY_SECOND: + solaxX1_EverySecond(); + break; #ifdef USE_WEBSERVER case FUNC_WEB_COL_SENSOR: case FUNC_WEB_SENSOR: From e2bae09dede1acc1a8076d878c7bdb699eaffec0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:41:11 +0100 Subject: [PATCH 178/205] Update changelogs --- CHANGELOG.md | 5 +++-- tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae5ecba05..361706386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ All notable changes to this project will be documented in this file. - ESP32 ULP lp_core to Berry ULP module (#22567) - Shelly 1 Gen3 template {"NAME":"Shelly 1 Gen3","GPIO":[0,0,0,4736,0,224,0,0,1,1,192,0,0,0,0,0,0,0,0,576,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000"} - Shelly 1PM Gen3 template {"NAME":"Shelly 1PM Gen3","GPIO":[0,32,0,4736,224,0,3200,8161,576,1,192,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000"} -- Shelly 2PM Gen3 template {"NAME":"Shelly 2PM Gen3","GPIO":[9472,3458,576,225,4736,224,640,608,1,1,193,0,0,0,0,0,0,0,192,32,1,1],"FLAG":0,"BASE":1,"CMND":"ADCGPIO4 10000,10000,4000"} +- Shelly 2PM Gen3 template {"NAME":"Shelly 2PM Gen3","GPIO":[9472,3458,576,225,4736,224,640,608,1,1,193,0,0,0,0,0,0,0,192,32,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio4 10000,10000,4000"} +- Shelly i4 Gen3 template {"NAME":"Shelly i4 Gen3","GPIO":[0,0,0,4736,32,195,194,193,1,1,192,0,0,0,0,0,0,0,0,0,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000} ### Breaking Changed - ESP32 ArtNet switches from GRB to RGB encoding (#22556) @@ -62,7 +63,7 @@ All notable changes to this project will be documented in this file. - Support for MS5837 pressure and temperature sensor (#22376) - Berry add I2C read16/write16 supporting Little Endian (#22448) - Berry drivers for PCA9535 (generic and in SenseCAP D1) (#22451) -- Shelly DALI Dimmer Gen3 template {"NAME":"Shelly DALI Dimmer Gen3","GPIO":[34,4736,0,3840,11360,11392,128,129,0,1,576,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1,"CMND":"ADCGPIO1 10000,10000,4000} +- Shelly DALI Dimmer Gen3 template {"NAME":"Shelly DALI Dimmer Gen3","GPIO":[34,4736,0,3840,11360,11392,128,129,0,1,576,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio1 10000,10000,4000} ### Changed - AHT1X/AHT2X/AHT3X ready for virtual I2C (#22427) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino index 31f15d109..31a6fd3c6 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino @@ -24,7 +24,7 @@ #ifdef USE_ENERGY_SENSOR #ifdef USE_ADE7953 /*********************************************************************************************\ - * ADE7953 - Energy used in Shelly 2.5 (model 1), EM (model 2), Plus 2PM (model 3), Pro 1PM (model 4), Pro 2PM (model 5) and Pro 4PM (model 6) + * ADE7953 - Energy used in Shelly 2.5 (model 1), EM (model 2), Plus 2PM and 2PM Gen3 (model 3), Pro 1PM (model 4), Pro 2PM (model 5) and Pro 4PM (model 6) * * {"NAME":"Shelly 2.5","GPIO":[320,0,32,0,224,193,0,0,640,192,608,225,3456,4736],"FLAG":0,"BASE":18} * {"NAME":"Shelly EM","GPIO":[0,0,0,0,0,0,0,0,640,3457,608,224,8832,1],"FLAG":0,"BASE":18} @@ -33,7 +33,7 @@ * {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"} * {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"} * {"NAME":"Shelly Pro 4PM","GPIO":[0,6210,0,6214,9568,0,0,0,0,0,9569,0,768,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,736,704,3461,0,4736,0,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"} - * {"NAME":"Shelly 2PM Gen3","GPIO":[9472,3458,576,225,4736,224,640,608,1,1,193,0,0,0,0,0,0,0,192,32,1,1],"FLAG":0,"BASE":1,"CMND":"ADCGPIO4 10000,10000,4000"} + * {"NAME":"Shelly 2PM Gen3","GPIO":[9472,3458,576,225,4736,224,640,608,1,1,193,0,0,0,0,0,0,0,192,32,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio4 10000,10000,4000"} * * Based on datasheet from https://www.analog.com/en/products/ade7953.html * From baeaad7558ee43d8b62d66f842269f7ccd16b32d Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Mon, 2 Dec 2024 12:10:28 +0100 Subject: [PATCH 179/205] fix LED, C2 has no i2s (#22575) --- tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino index 5ff5d94dd..e6caffc43 100644 --- a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino +++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino @@ -97,7 +97,7 @@ const uint16_t kTasLed_Type = kTasLed_PixelSize | kTasLed_PixelOrder | kTasLed_P // select hardware acceleration - bitbanging is not supported on ESP32 due to interference of interrupts #if CONFIG_IDF_TARGET_ESP32C2 - const uint32_t kTasLed_Hardware = TasmotaLed_I2S; // I2S + const uint32_t kTasLed_Hardware = TasmotaLed_SPI; // no I2S for the C2 #else // all other ESP32 variants #if defined(USE_WS2812_DMA) const uint32_t kTasLed_Hardware = TasmotaLed_RMT; // default DMA to RMT From ebff2d2d3861031609611254e0e03c43e0a97ac5 Mon Sep 17 00:00:00 2001 From: Felix Laevsky Date: Mon, 2 Dec 2024 13:11:05 +0200 Subject: [PATCH 180/205] Explanation for BLEMinRssiLevel command added in the comments (#22550) --- tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino index a8bdf572b..0528d579f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino @@ -111,6 +111,8 @@ BLEFilterNames BLEFilterNames0 - clear filter list BLEFilterNames1 - , - set one or more device names + BLEMinRssiLevel + BLEMinRssiLevel - Sets the minimum allowable RSSI level for detected devices Other drivers can add callbacks to receive advertisements Other drivers can add 'operations' to be performed and receive callbacks from the operation's success or failure From 341cc87527be5e931bd69ce9720e9f3712302fa6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:15:46 +0100 Subject: [PATCH 181/205] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 361706386..ad0ebd2a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ All notable changes to this project will be documented in this file. - Magic switch applying masking window to any power change (#22535) - Shift595 output offsets and restart relay toggles - Shutter wrong power ON state (#22548) +- ESP32-C2 TasmotaLED from not present I2S to SPI (#22575) ### Removed From 62d6a0333591bfedca797d0d42b02f5502d7cdf5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:12:53 +0100 Subject: [PATCH 182/205] Fix non-sequential shutter GUI display --- .../xdrv_01_9_webserver.ino | 63 +++++++++---------- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 3526aec65..ec03b9de1 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1254,7 +1254,7 @@ int32_t IsShutterWebButton(uint32_t idx) { /*-------------------------------------------------------------------------------------------*/ -void WebGetDeviceCounts(uint32_t &buttons_non_light, uint32_t &buttons_non_light_non_shutter, uint32_t &shutter_button) { +void WebGetDeviceCounts(uint32_t &buttons_non_light, uint32_t &buttons_non_light_non_shutter, uint32_t &shutter_button_mask) { buttons_non_light = TasmotaGlobal.devices_present; #ifdef USE_LIGHT @@ -1266,7 +1266,7 @@ void WebGetDeviceCounts(uint32_t &buttons_non_light, uint32_t &buttons_non_light #endif // USE_LIGHT buttons_non_light_non_shutter = buttons_non_light; - shutter_button = 0; // Bitmask for each button + shutter_button_mask = 0; // Bitmask for each button #ifdef USE_SHUTTER // Chk for reduced toggle buttons used by shutters // Find and skip dedicated shutter buttons @@ -1274,7 +1274,7 @@ void WebGetDeviceCounts(uint32_t &buttons_non_light, uint32_t &buttons_non_light for (uint32_t button_idx = 1; button_idx <= buttons_non_light; button_idx++) { if (IsShutterWebButton(button_idx) != 0) { buttons_non_light_non_shutter--; - shutter_button |= (1 << (button_idx -1)); // Set button bit in bitmask + shutter_button_mask |= (1 << (button_idx -1)); // Set button bit in bitmask } } } @@ -1365,12 +1365,11 @@ void HandleRoot(void) { if (TasmotaGlobal.devices_present) { uint32_t buttons_non_light; uint32_t buttons_non_light_non_shutter; - uint32_t shutter_button; - WebGetDeviceCounts(buttons_non_light, buttons_non_light_non_shutter, shutter_button); + uint32_t shutter_button_mask; + WebGetDeviceCounts(buttons_non_light, buttons_non_light_non_shutter, shutter_button_mask); uint32_t button_idx = 1; - if (buttons_non_light_non_shutter) { // Any non light AND non shutter button - // Display toggle buttons + if (buttons_non_light_non_shutter) { // Any non light AND non shutter button - Show toggle buttons WSContentSend_P(HTTP_TABLE100); // "" WSContentSend_P(PSTR("")); @@ -1398,7 +1397,7 @@ void HandleRoot(void) { for (button_idx = 1; button_idx <= buttons_non_light; button_idx++) { #ifdef USE_SHUTTER - if (bitRead(shutter_button, button_idx -1)) { continue; } // Skip non-sequential shutter button + if (bitRead(shutter_button_mask, button_idx -1)) { continue; } // Skip non-sequential shutter button #endif // USE_SHUTTER bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); @@ -1417,33 +1416,29 @@ void HandleRoot(void) { } #ifdef USE_SHUTTER - if (shutter_button) { // Any button bit set - WSContentSend_P(HTTP_TABLE100); // "
" - - int32_t ShutterWebButton; - uint32_t shutter_button_idx = 1; + if (TasmotaGlobal.shutters_present) { // Any shutter present - Show shutter buttons and slider + WSContentSend_P(HTTP_TABLE100); // "
" + uint32_t shutter_button_idx; uint32_t shutter_button_idx_temp; - for (uint32_t shutter_idx = 0; shutter_idx < TasmotaGlobal.shutters_present ; shutter_idx++) { - while ((0 == shutter_button & (1 << (shutter_button_idx -1)))) { shutter_button_idx++; } - + for (uint32_t shutter_idx = 0; shutter_idx < TasmotaGlobal.shutters_present; shutter_idx++) { WSContentSend_P(PSTR("")); - shutter_button_idx++; // Left button is next button first (down) + uint32_t shutter_options = ShutterGetOptions(shutter_idx); + shutter_button_idx = ShutterGetStartRelay(shutter_idx) +1; // Left button is next button first (down) for (uint32_t j = 0; j < 2; j++) { - ShutterWebButton = IsShutterWebButton(shutter_button_idx); - shutter_button_idx_temp = ShutterGetOptions(abs(ShutterWebButton)-1) & 1 /* invert index */ ? shutter_button_idx + (j * 2) - 1 : shutter_button_idx; - // AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: j %d, ShutterWebButton %d, shutter_button_idx %d, shutter_idx %d, shutter_button_idx_temp %d"), j, ShutterWebButton, shutter_button_idx, shutter_idx, shutter_button_idx_temp); + shutter_button_idx_temp = (shutter_options & 1) ? shutter_button_idx + (j * 2) - 1 : shutter_button_idx; // Invert index +// AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: j %d, shutter_idx %d, shutter_button_idx %d, shutter_idx %d, shutter_button_idx_temp %d"), j, shutter_idx, shutter_button_idx, shutter_idx, shutter_button_idx_temp); WSContentSend_P(HTTP_DEVICE_CONTROL, 15, shutter_button_idx_temp, shutter_button_idx_temp, - ((ShutterGetOptions(abs(ShutterWebButton)-1) & 2) /* is locked */ ? "-" : - ((ShutterGetOptions(abs(ShutterWebButton)-1) & 1) /* invert web buttons */ ? (j ? "▼" : "▲") : (j ? "▲" : "▼"))), + ((shutter_options & 2) ? "-" : // Is locked + ((shutter_options & 1) ? (j ? "▼" : "▲") : (j ? "▲" : "▼"))), // Invert web buttons ""); - if (1 == j) { break; } + if (1 == j) { break; } // Both buttons shown - shutter_button_idx--; // Right button is previous button (up) + shutter_button_idx--; // Right button is previous button (up) bool set_button = ((shutter_button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(shutter_button_idx -1))); snprintf_P(stemp, sizeof(stemp), PSTR("Shutter %d"), shutter_idx +1); uint32_t shutter_real_to_percent_position = ShutterRealToPercentPosition(-9999, shutter_idx); - Web.shutter_slider[shutter_idx] = (ShutterGetOptions(shutter_idx) & 1) ? (100 - shutter_real_to_percent_position) : shutter_real_to_percent_position; + Web.shutter_slider[shutter_idx] = (shutter_options & 1) ? (100 - shutter_real_to_percent_position) : shutter_real_to_percent_position; WSContentSend_P(HTTP_MSG_SLIDER_SHUTTER, (set_button) ? HtmlEscape(GetWebButton(shutter_button_idx -1)).c_str() : stemp, shutter_idx +1, @@ -1451,20 +1446,18 @@ void HandleRoot(void) { shutter_idx +1); } WSContentSend_P(PSTR("")); - shutter_button_idx += 2; - } WSContentSend_P(PSTR("
")); - if (1 == button_idx) { - button_idx = shutter_button_idx; + if (1 == button_idx) { // No power/display button + button_idx = shutter_button_idx +2; } } #endif // USE_SHUTTER #ifdef USE_LIGHT - if (TasmotaGlobal.light_type) { - WSContentSend_P(HTTP_TABLE100); // "" + if (TasmotaGlobal.light_type) { // Any light - Show light button and slider(s) + WSContentSend_P(HTTP_TABLE100); // "
" uint8_t light_subtype = TasmotaGlobal.light_type &7; if (!Settings->flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM @@ -1474,7 +1467,7 @@ void HandleRoot(void) { WebSliderColdWarm(); } - if (light_subtype > 2) { // No W or CW + if (light_subtype > 2) { // No W or CW uint16_t hue; uint8_t sat; LightGetHSB(&hue, &sat, nullptr); @@ -1908,8 +1901,8 @@ bool HandleRootStatusRefresh(void) { uint32_t buttons_non_light; uint32_t buttons_non_light_non_shutter; - uint32_t shutter_button; - WebGetDeviceCounts(buttons_non_light, buttons_non_light_non_shutter, shutter_button); + uint32_t shutter_button_mask; + WebGetDeviceCounts(buttons_non_light, buttons_non_light_non_shutter, shutter_button_mask); if (buttons_non_light_non_shutter <= 8) { // Any non light AND non shutter button WSContentSend_P(PSTR("{t}")); @@ -1918,7 +1911,7 @@ bool HandleRootStatusRefresh(void) { for (uint32_t idx = 1; idx <= buttons_non_light; idx++) { #ifdef USE_SHUTTER - if (bitRead(shutter_button, idx -1)) { continue; } // Skip non-sequential shutter button + if (bitRead(shutter_button_mask, idx -1)) { continue; } // Skip non-sequential shutter button #endif // USE_SHUTTER snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(TasmotaGlobal.power, idx -1)); From 4046cd8ec0fda76a92d9a27ea409e7f03e105f81 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:28:38 +0100 Subject: [PATCH 183/205] Add show Active Power Total with any multi-phase energy monitoring (#22579) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 7 ++++--- tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino | 7 ++++--- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad0ebd2a4..6017cc034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. - Shelly 1PM Gen3 template {"NAME":"Shelly 1PM Gen3","GPIO":[0,32,0,4736,224,0,3200,8161,576,1,192,0,0,0,0,0,0,0,0,1,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000"} - Shelly 2PM Gen3 template {"NAME":"Shelly 2PM Gen3","GPIO":[9472,3458,576,225,4736,224,640,608,1,1,193,0,0,0,0,0,0,0,192,32,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio4 10000,10000,4000"} - Shelly i4 Gen3 template {"NAME":"Shelly i4 Gen3","GPIO":[0,0,0,4736,32,195,194,193,1,1,192,0,0,0,0,0,0,0,0,0,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000} +- Show Active Power Total with any multi-phase energy monitoring (#22579) ### Breaking Changed - ESP32 ArtNet switches from GRB to RGB encoding (#22556) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 67289a9b5..873b43eeb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -138,6 +138,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC [#22370](https://github.com/arendst/Tasmota/issues/22370) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) +- Show Active Power Total with any multi-phase energy monitoring [#22579](https://github.com/arendst/Tasmota/issues/22579) - ESP32 ULP lp_core to Berry ULP module (#22567)[#22567](https://github.com/arendst/Tasmota/issues/22567) - ESP32 new BLE filters by name and minimum RSSI [#22530](https://github.com/arendst/Tasmota/issues/22530) - ESP32 Hybrid compile take custom boards settings in account [#22542](https://github.com/arendst/Tasmota/issues/22542) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino index baec24922..ae9086cfd 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino @@ -1472,6 +1472,10 @@ void EnergyShow(bool json) { WSContentSend_PD(HTTP_SNS_CURRENT, WebEnergyFmt(Energy->current, Settings->flag2.current_resolution)); } WSContentSend_PD(HTTP_SNS_POWER, WebEnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution)); +// if (abs(negative_phases) != Energy->phase_count) { // Provide total power if producing power (PV) and multi phase + if (Energy->phase_count > 1) { // Provide total power if multi phase + WSContentSend_PD(HTTP_SNS_POWER_TOTAL, WebEnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution, 3)); + } if (!Energy->type_dc) { if (Energy->current_available && Energy->voltage_available) { WSContentSend_PD(HTTP_SNS_POWERUSAGE_APPARENT, WebEnergyFmt(apparent_power, Settings->flag2.wattage_resolution)); @@ -1479,9 +1483,6 @@ void EnergyShow(bool json) { WSContentSend_PD(HTTP_SNS_POWER_FACTOR, WebEnergyFmt(power_factor, 2)); } } - if (abs(negative_phases) != Energy->phase_count) { // Provide total power if producing power (PV) and multi phase - WSContentSend_PD(HTTP_SNS_POWER_TOTAL, WebEnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution, 3)); - } WSContentSend_PD(HTTP_SNS_ENERGY_TODAY, WebEnergyFmt(Energy->daily, Settings->flag2.energy_resolution, 2)); WSContentSend_PD(HTTP_SNS_ENERGY_YESTERDAY, WebEnergyFmt(energy_yesterday_ph, Settings->flag2.energy_resolution, 2)); WSContentSend_PD(HTTP_SNS_ENERGY_TOTAL, WebEnergyFmt(Energy->total, Settings->flag2.energy_resolution, 2)); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index a30880199..e44ec4fa5 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -1862,6 +1862,10 @@ void EnergyShow(bool json) { WSContentSend_PD(HTTP_SNS_CURRENT, WebEnergyFmt(Energy->current, Settings->flag2.current_resolution)); } WSContentSend_PD(HTTP_SNS_POWER, WebEnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution)); +// if (abs(negative_phases) != Energy->phase_count) { // Provide total power if producing power (PV) and multi phase + if (Energy->phase_count > 1) { // Provide total power if multi phase + WSContentSend_PD(HTTP_SNS_POWER_TOTAL, WebEnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution, 3)); + } if (!Energy->type_dc) { if (Energy->current_available && Energy->voltage_available) { WSContentSend_PD(HTTP_SNS_POWERUSAGE_APPARENT, WebEnergyFmt(apparent_power, Settings->flag2.wattage_resolution)); @@ -1869,9 +1873,6 @@ void EnergyShow(bool json) { WSContentSend_PD(HTTP_SNS_POWER_FACTOR, WebEnergyFmt(power_factor, 2)); } } - if (abs(negative_phases) != Energy->phase_count) { // Provide total power if producing power (PV) and multi phase - WSContentSend_PD(HTTP_SNS_POWER_TOTAL, WebEnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution, 3)); - } WSContentSend_PD(HTTP_SNS_ENERGY_TODAY, WebEnergyFmt(Energy->daily_kWh, Settings->flag2.energy_resolution, 2)); WSContentSend_PD(HTTP_SNS_ENERGY_YESTERDAY, WebEnergyFmt(energy_yesterday_kWh, Settings->flag2.energy_resolution, 2)); WSContentSend_PD(HTTP_SNS_ENERGY_TOTAL, WebEnergyFmt(Energy->total, Settings->flag2.energy_resolution, 2)); From 62e4bf1acd54ffad5ee66050126d6364b2fbad1e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:34:48 +0100 Subject: [PATCH 184/205] Add command `SetOption162 1` to disable adding export energy to energy today (#22578) --- CHANGELOG.md | 1 + RELEASENOTES.md | 3 ++- tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 4 +++- tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino | 4 +++- tools/decode-status.py | 7 ++++--- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6017cc034..762bcad53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file. - Shelly 2PM Gen3 template {"NAME":"Shelly 2PM Gen3","GPIO":[9472,3458,576,225,4736,224,640,608,1,1,193,0,0,0,0,0,0,0,192,32,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio4 10000,10000,4000"} - Shelly i4 Gen3 template {"NAME":"Shelly i4 Gen3","GPIO":[0,0,0,4736,32,195,194,193,1,1,192,0,0,0,0,0,0,0,0,0,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000} - Show Active Power Total with any multi-phase energy monitoring (#22579) +- Command `SetOption162 1` to disable adding export energy to energy today (#22578) ### Breaking Changed - ESP32 ArtNet switches from GRB to RGB encoding (#22556) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 873b43eeb..438b246e3 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -117,7 +117,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ## Changelog v14.3.0.7 ### Added - Command `WebColor20` to control color of Button when Off -- Command `SetOption161 1` to disable display of state text (#22515) +- Command `SetOption161 1` to disable display of state text [#22515](https://github.com/arendst/Tasmota/issues/22515) +- Command `SetOption162 1` to disable adding export energy to energy today [#22578](https://github.com/arendst/Tasmota/issues/22578) - DALI support for short addresses (gear) and groups - DALI command `DaliGear` to set max found gear to speed up scan response - DALI command `DaliGroup` to add gear to groups diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino index ae9086cfd..aae18311e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino @@ -278,7 +278,9 @@ void EnergyUpdateToday(void) { int32_t delta = Energy->kWhtoday_delta[i] / 1000; delta_sum_balanced += delta; Energy->kWhtoday_delta[i] -= (delta * 1000); - Energy->kWhtoday[i] += delta; + if (!Settings->flag6.no_export_energy_today || (delta > 0)) { // SetOption162 - (Energy) Do not add export energy to energy today (1) + Energy->kWhtoday[i] += delta; + } if (delta < 0) { // Export energy Energy->kWhtoday_export[i] += (delta *-1); if (Energy->kWhtoday_export[i] > 100) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index e44ec4fa5..e8ec16a2b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -543,7 +543,9 @@ void EnergyUpdateToday(void) { int32_t delta = Energy->kWhtoday_delta[i] / 1000; delta_sum_balanced += delta; Energy->kWhtoday_delta[i] -= (delta * 1000); - Energy->kWhtoday[i] += delta; + if (!Settings->flag6.no_export_energy_today || (delta > 0)) { // SetOption162 - (Energy) Do not add export energy to energy today (1) + Energy->kWhtoday[i] += delta; + } if (delta < 0) { // Export energy RtcEnergySettings.energy_export_kWh[i] += ((float)(delta / 100) *-1) / 1000; } diff --git a/tools/decode-status.py b/tools/decode-status.py index dd487a206..d8d9076af 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -216,8 +216,9 @@ a_setoption = [[ "(MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead", "(Counter) Enable counting on both rising and falling edge (1)", "(LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1)", - "", - "","","","", + "(GUI) Disable display of state text (1)", + "(Energy) Do not add export energy to energy today (1)", + "","","", "","","","", "","","","", "","","","" @@ -340,7 +341,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v14.3.0.5 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v14.3.0.7 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 570e2052d3b91fd0b21a5433f577840c8b7cee9e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:37:39 +0100 Subject: [PATCH 185/205] Fix compilation --- tasmota/include/tasmota_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index dceb236ec..c0cb9959b 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -196,7 +196,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t counter_both_edges : 1; // bit 13 (v13.3.0.5) - SetOption159 - (Counter) Enable counting on both rising and falling edge (1) uint32_t ld2410_use_pin : 1; // bit 14 (v14.3.0.2) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1) uint32_t gui_no_state_text : 1; // bit 15 (v14.3.0.7) - SetOption161 - (GUI) Disable display of state text (1) - uint32_t spare16 : 1; // bit 16 + uint32_t no_export_energy_today : 1; // bit 16 (v14.3.0.7) - SetOption162 - (Energy) Do not add export energy to energy today (1) uint32_t spare17 : 1; // bit 17 uint32_t spare18 : 1; // bit 18 uint32_t spare19 : 1; // bit 19 From 6b753cff4458ce2564793f51040b1028f251a1a1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:15:14 +0100 Subject: [PATCH 186/205] Fix ESP32 Shift595 relay click on restart --- tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino index 513723c7f..3e20116a2 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino @@ -63,6 +63,11 @@ void Shift595ModuleInit(void) { Shift595ConfigurePin(Shift595->pinSRCLK); Shift595ConfigurePin(Shift595->pinRCLK); Shift595ConfigurePin(Shift595->pinSER); +#ifdef ESP32 + // Release hold on clocks (if set before restart) + gpio_hold_dis((gpio_num_t)Shift595->pinSRCLK); + gpio_hold_dis((gpio_num_t)Shift595->pinRCLK); +#endif if (PinUsed(GPIO_SHIFT595_OE)) { Shift595->pinOE = Pin(GPIO_SHIFT595_OE); @@ -142,6 +147,13 @@ bool Xdrv60(uint32_t function) { case FUNC_SET_POWER: Shift595SwitchRelay(); break; +#ifdef ESP32 + case FUNC_SAVE_BEFORE_RESTART: + // Set hold on clocks to disable relay click on restart + gpio_hold_en((gpio_num_t)Shift595->pinSRCLK); + gpio_hold_en((gpio_num_t)Shift595->pinRCLK); + break; +#endif // ESP32 case FUNC_COMMAND: result = DecodeCommand(kShift595Commands, Shift595Command); break; From f72769252ed89c8ef414adb77192c89f610bef19 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:52:00 +0100 Subject: [PATCH 187/205] Fix KNX Scenes index change regression from v14.2.0.4 (#22405) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/include/tasmota.h | 14 ++-- tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino | 76 +++++++++++++-------- 4 files changed, 58 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 762bcad53..1beab31d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ All notable changes to this project will be documented in this file. - Shift595 output offsets and restart relay toggles - Shutter wrong power ON state (#22548) - ESP32-C2 TasmotaLED from not present I2S to SPI (#22575) +- KNX Scenes index change regression from v14.2.0.4 (#22405) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 438b246e3..341f1e172 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -177,6 +177,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Shift595 output offsets and restart relay toggles - Use HTML escape on File System Edit File load [#22492](https://github.com/arendst/Tasmota/issues/22492) - Prevent crashing when `display.ini` is missing end `#` [#22471](https://github.com/arendst/Tasmota/issues/22471) +- KNX Scenes index change regression from v14.2.0.4 [#22405](https://github.com/arendst/Tasmota/issues/22405) - Magic switch applying masking window to any power change [#22535](https://github.com/arendst/Tasmota/issues/22535) - Shutter wrong power ON state [#22548](https://github.com/arendst/Tasmota/issues/22548) - Alexa Hue with multiple devices [#22383](https://github.com/arendst/Tasmota/issues/22383) diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index a9983cc04..79a3cc486 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -279,13 +279,13 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to #define KNX_SLOT3 28 #define KNX_SLOT4 29 #define KNX_SLOT5 30 -#define KNX_SLOT6 31 -#define KNX_SLOT7 32 -#define KNX_SLOT8 33 -#define KNX_SLOT9 34 -#define KNX_SCENE 35 -#define KNX_DIMMER 36 // aka DPT_Scaling 5.001 -#define KNX_COLOUR 37 // aka DPT_Colour_RGB 232.600 or DPT_Colour_RGBW 251.600 +#define KNX_SCENE 31 +#define KNX_DIMMER 32 // aka DPT_Scaling 5.001 +#define KNX_COLOUR 33 // aka DPT_Colour_RGB 232.600 or DPT_Colour_RGBW 251.600 +#define KNX_SLOT6 34 +#define KNX_SLOT7 35 +#define KNX_SLOT8 36 +#define KNX_SLOT9 37 #define KNX_MAX_device_param 37 #define MAX_KNXTX_CMNDS 9 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino index d40c11f34..f6a206f6b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino @@ -84,6 +84,18 @@ typedef struct __device_parameters // - Multiples address to the same callback (i.e. Set Relay 1 Status) are used on scenes for example } device_parameters_t; +uint8_t knx_slot_xref[] = { + KNX_SLOT1, + KNX_SLOT2, + KNX_SLOT3, + KNX_SLOT4, + KNX_SLOT5, + KNX_SLOT6, + KNX_SLOT7, + KNX_SLOT8, + KNX_SLOT9 +}; + // device parameters (information that can be sent) device_parameters_t device_param[] = { { 1, false, false, KNX_Empty }, // device_param[ 0] = Relay 1 @@ -116,13 +128,13 @@ device_parameters_t device_param[] = { { KNX_SLOT3 , false, false, KNX_Empty }, { KNX_SLOT4 , false, false, KNX_Empty }, { KNX_SLOT5 , false, false, KNX_Empty }, + { KNX_SCENE , false, false, KNX_Empty }, + { KNX_DIMMER , false, false, KNX_Empty }, + { KNX_COLOUR , false, false, KNX_Empty }, { KNX_SLOT6 , false, false, KNX_Empty }, { KNX_SLOT7 , false, false, KNX_Empty }, { KNX_SLOT8 , false, false, KNX_Empty }, { KNX_SLOT9 , false, false, KNX_Empty }, - { KNX_SCENE , false, false, KNX_Empty }, - { KNX_DIMMER , false, false, KNX_Empty }, - { KNX_COLOUR , false, false, KNX_Empty }, { KNX_Empty, false, false, KNX_Empty} }; @@ -158,13 +170,13 @@ const char * device_param_ga[] = { D_KNX_TX_SLOT " 3", D_KNX_TX_SLOT " 4", D_KNX_TX_SLOT " 5", + D_KNX_TX_SCENE , + D_BRIGHTLIGHT , + D_COLOR , D_KNX_TX_SLOT " 6", D_KNX_TX_SLOT " 7", D_KNX_TX_SLOT " 8", D_KNX_TX_SLOT " 9", - D_KNX_TX_SCENE , - D_BRIGHTLIGHT , - D_COLOR , nullptr }; @@ -200,14 +212,14 @@ const char *device_param_cb[] = { D_KNX_RX_SLOT " 3", D_KNX_RX_SLOT " 4", D_KNX_RX_SLOT " 5", + D_KNX_RX_SCENE , + D_BRIGHTLIGHT , + D_COLOR , D_KNX_RX_SLOT " 6", D_KNX_RX_SLOT " 7", D_KNX_RX_SLOT " 8", D_KNX_RX_SLOT " 9", - D_KNX_RX_SCENE , - D_BRIGHTLIGHT , - D_COLOR , -nullptr + nullptr }; // Commands @@ -720,16 +732,21 @@ void KNX_CB_Action(message_t const &msg, void *arg) } #if defined(USE_RULES) || defined(USE_SCRIPT) - else if ((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT9)) // KNX RX SLOTs (write command) + else if (((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT5)) || + ((chan->type >= KNX_SLOT6) && (chan->type <= KNX_SLOT9))) // KNX RX SLOTs (write command) { if (!toggle_inhibit) { + uint32_t slot_offset = KNX_SLOT1; + if (chan->type >= KNX_SLOT6) { + slot_offset = KNX_SLOT6; + } char command[35]; //4294967295.00 13chars + 17 if (msg.data_len == 1) { // Command received - snprintf_P(command, sizeof(command), PSTR("event KNXRX_CMND%d=%d"), ((chan->type) - KNX_SLOT1 + 1 ), msg.data[0]); + snprintf_P(command, sizeof(command), PSTR("event KNXRX_CMND%d=%d"), ((chan->type) - slot_offset + 1 ), msg.data[0]); } else { // Value received - snprintf_P(command, sizeof(command), PSTR("event KNXRX_VAL%d=%s"), ((chan->type) - KNX_SLOT1 + 1 ), tempchar); + snprintf_P(command, sizeof(command), PSTR("event KNXRX_VAL%d=%s"), ((chan->type) - slot_offset + 1 ), tempchar); } ExecuteCommand(command, SRC_KNX); if (Settings->flag.knx_enable_enhancement) { @@ -830,11 +847,16 @@ void KNX_CB_Action(message_t const &msg, void *arg) #if defined(USE_RULES) || defined(USE_SCRIPT) - else if ((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT9)) // KNX RX SLOTs (read command) + else if (((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT5)) || + ((chan->type >= KNX_SLOT6) && (chan->type <= KNX_SLOT9))) // KNX RX SLOTs (read command) { if (!toggle_inhibit) { + uint32_t slot_offset = KNX_SLOT1; + if (chan->type >= KNX_SLOT6) { + slot_offset = KNX_SLOT6; + } char command[25]; - snprintf_P(command, sizeof(command), PSTR("event KNXRX_REQ%d"), ((chan->type) - KNX_SLOT1 + 1 ) ); + snprintf_P(command, sizeof(command), PSTR("event KNXRX_REQ%d"), ((chan->type) - slot_offset + 1 ) ); ExecuteCommand(command, SRC_KNX); if (Settings->flag.knx_enable_enhancement) { toggle_inhibit = TOGGLE_INHIBIT_TIME; @@ -1258,16 +1280,16 @@ void CmndKnxTxCmnd(void) // XdrvMailbox.index <- KNX SLOT to use // XdrvMailbox.payload <- data to send // Search all the registered GA that has that output (variable: KNX SLOTx) as parameter - uint8_t i = KNX_GA_Search(XdrvMailbox.index + KNX_SLOT1 -1); + uint8_t i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1]); while ( i != KNX_Empty ) { KNX_addr.value = Settings->knx_GA_addr[i]; KNX_WRITE_1BIT(KNX_addr, !(XdrvMailbox.payload == 0)); AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %d " D_SENT_TO " %d/%d/%d"), - device_param_ga[XdrvMailbox.index + KNX_SLOT1 -2], !(XdrvMailbox.payload == 0), + device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], !(XdrvMailbox.payload == 0), KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); - i = KNX_GA_Search(XdrvMailbox.index + KNX_SLOT1 -1, i + 1); + i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1], i + 1); } ResponseCmndIdxChar (XdrvMailbox.data ); } @@ -1279,7 +1301,7 @@ void CmndKnxTxVal(void) // XdrvMailbox.index <- KNX SLOT to use // XdrvMailbox.payload <- data to send // Search all the registered GA that has that output (variable: KNX SLOTx) as parameter - uint8_t i = KNX_GA_Search(XdrvMailbox.index + KNX_SLOT1 -1); + uint8_t i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1]); while ( i != KNX_Empty ) { KNX_addr.value = Settings->knx_GA_addr[i]; @@ -1289,10 +1311,10 @@ void CmndKnxTxVal(void) KNX_WRITE_4BYTE_FLOAT(KNX_addr, tempvar); AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d/%d/%d"), - device_param_ga[XdrvMailbox.index + KNX_SLOT1 -2], XdrvMailbox.data, + device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], XdrvMailbox.data, KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); - i = KNX_GA_Search(XdrvMailbox.index + KNX_SLOT1 -1, i + 1); + i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1], i + 1); } ResponseCmndIdxChar (XdrvMailbox.data ); } @@ -1305,7 +1327,7 @@ void CmndKnxTxFloat(void) // XdrvMailbox.index <- KNX SLOT to use // XdrvMailbox.payload <- data to send // Search all the registered GA that has that output (variable: KNX SLOTx) as parameter - uint8_t i = KNX_GA_Search(XdrvMailbox.index + KNX_SLOT1 -1); + uint8_t i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1]); while ( i != KNX_Empty ) { KNX_addr.value = Settings->knx_GA_addr[i]; @@ -1315,10 +1337,10 @@ void CmndKnxTxFloat(void) KNX_WRITE_2BYTE_FLOAT(KNX_addr, tempvar); AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d/%d/%d (2 bytes float)"), - device_param_ga[XdrvMailbox.index + KNX_SLOT1 -2], XdrvMailbox.data, + device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], XdrvMailbox.data, KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); - i = KNX_GA_Search(XdrvMailbox.index + KNX_SLOT1 -1, i + 1); + i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1], i + 1); } ResponseCmndIdxChar (XdrvMailbox.data ); } @@ -1330,7 +1352,7 @@ void CmndKnxTxByte(void) // XdrvMailbox.index <- KNX SLOT to use // XdrvMailbox.payload <- data to send // Search all the registered GA that has that output (variable: KNX SLOTx) as parameter - uint8_t i = KNX_GA_Search(XdrvMailbox.index + KNX_SLOT1 -1); + uint8_t i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1]); while ( i != KNX_Empty ) { KNX_addr.value = Settings->knx_GA_addr[i]; @@ -1340,10 +1362,10 @@ void CmndKnxTxByte(void) KNX_WRITE_1BYTE_UINT(KNX_addr, tempvar); AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d/%d/%d (1 byte unsigned)"), - device_param_ga[XdrvMailbox.index + KNX_SLOT1 -2], XdrvMailbox.data, + device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], XdrvMailbox.data, KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); - i = KNX_GA_Search(XdrvMailbox.index + KNX_SLOT1 -1, i + 1); + i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1], i + 1); } ResponseCmndIdxChar (XdrvMailbox.data ); } From ccd76b26ed8c309b3a413b39535d5309bb1abc9e Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 4 Dec 2024 11:43:51 +0100 Subject: [PATCH 188/205] Re-enable shutter report on teleperiod (#22586) * Reactivate shutter report on teleperiod * Reactivate shutter report on teleperiod --- tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index 539925152..a26d1a6b1 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -2383,7 +2383,7 @@ bool Xdrv27(uint32_t function) } break; case FUNC_JSON_APPEND: - if (!ShutterGlobal.sensor_data_reported) { + if (!ShutterGlobal.sensor_data_reported || TasmotaGlobal.tele_period == 0) { ShutterGlobal.sensor_data_reported = true; for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) { ResponseAppend_P(","); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 7bc096a4b..282924839 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -1974,7 +1974,7 @@ bool Xdrv27(uint32_t function) } break; case FUNC_JSON_APPEND: - if (!sensor_data_reported) { + if (!sensor_data_reported || TasmotaGlobal.tele_period == 0) { sensor_data_reported = true; for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) { uint8_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); From b80cc6a3e66a7dcf011a8f40202093b2961d67b6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:31:14 +0100 Subject: [PATCH 189/205] Fix select list and possible input buffer overflow (#22405) --- tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino | 166 +++++++++++--------- 1 file changed, 96 insertions(+), 70 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino index f6a206f6b..532215e04 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino @@ -52,19 +52,14 @@ uint8_t Settings->knx_CB_param[MAX_KNX_CB] Type of Output (set relay, #include // KNX Library -bool knx_started = false; +#define TOGGLE_INHIBIT_TIME 15 // 15*50mseg = 750mseg (inhibit time for not toggling again relays by a KNX toggle command) -address_t KNX_physs_addr; // Physical KNX address of this device -address_t KNX_addr; // KNX Address converter variable +#ifndef KNX_ENHANCEMENT_REPEAT +#define KNX_ENHANCEMENT_REPEAT 3 +#endif #define KNX_Empty 255 -#define TOGGLE_INHIBIT_TIME 15 // 15*50mseg = 750mseg (inhibit time for not toggling again relays by a KNX toggle command) - -float last_temp; -float last_hum; -uint8_t toggle_inhibit; - typedef struct __device_parameters { uint8_t type; // PARAMETER_ID. Used as type of GA = relay, button, sensor, etc, (INPUTS) @@ -84,18 +79,6 @@ typedef struct __device_parameters // - Multiples address to the same callback (i.e. Set Relay 1 Status) are used on scenes for example } device_parameters_t; -uint8_t knx_slot_xref[] = { - KNX_SLOT1, - KNX_SLOT2, - KNX_SLOT3, - KNX_SLOT4, - KNX_SLOT5, - KNX_SLOT6, - KNX_SLOT7, - KNX_SLOT8, - KNX_SLOT9 -}; - // device parameters (information that can be sent) device_parameters_t device_param[] = { { 1, false, false, KNX_Empty }, // device_param[ 0] = Relay 1 @@ -222,6 +205,43 @@ const char *device_param_cb[] = { nullptr }; +uint8_t knx_slot_xref[] = { + KNX_SLOT1, + KNX_SLOT2, + KNX_SLOT3, + KNX_SLOT4, + KNX_SLOT5, + KNX_SLOT6, + KNX_SLOT7, + KNX_SLOT8, + KNX_SLOT9 +}; + +uint8_t knx_select_nice_list[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + KNX_TEMPERATURE -1, + KNX_HUMIDITY -1, + KNX_ENERGY_VOLTAGE -1, + KNX_ENERGY_CURRENT -1, + KNX_ENERGY_POWER -1, + KNX_ENERGY_POWERFACTOR -1, + KNX_ENERGY_DAILY -1, + KNX_ENERGY_YESTERDAY -1, + KNX_ENERGY_TOTAL -1, + KNX_SLOT1 -1, + KNX_SLOT2 -1, + KNX_SLOT3 -1, + KNX_SLOT4 -1, + KNX_SLOT5 -1, + KNX_SLOT6 -1, + KNX_SLOT7 -1, + KNX_SLOT8 -1, + KNX_SLOT9 -1, + KNX_SCENE -1, + KNX_DIMMER -1, + KNX_COLOUR -1 +}; + // Commands #define D_PRFX_KNX "Knx" #define D_CMND_KNXTXCMND "Tx_Cmnd" @@ -236,19 +256,27 @@ const char *device_param_cb[] = { #define D_CMND_KNXTXDOUBLE "Tx_Double" // 4 bytes float (DPT14) #define D_CMND_KNXTXBYTE "Tx_Byte" // 1 byte unsigned (DPT5) - const char kKnxCommands[] PROGMEM = D_PRFX_KNX "|" // Prefix - D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL "|" D_CMND_KNX_ENABLED "|" D_CMND_KNX_ENHANCED "|" D_CMND_KNX_PA "|" D_CMND_KNX_GA "|" D_CMND_KNX_CB "|" D_CMND_KNXTXSCENE "|" + D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL "|" D_CMND_KNX_ENABLED "|" D_CMND_KNX_ENHANCED "|" + D_CMND_KNX_PA "|" D_CMND_KNX_GA "|" D_CMND_KNX_CB "|" D_CMND_KNXTXSCENE "|" D_CMND_KNXTXFLOAT "|" D_CMND_KNXTXDOUBLE "|" D_CMND_KNXTXBYTE; void (* const KnxCommand[])(void) PROGMEM = { - &CmndKnxTxCmnd, &CmndKnxTxVal, &CmndKnxEnabled, &CmndKnxEnhanced, &CmndKnxPa, &CmndKnxGa, &CmndKnxCb, &CmndKnxTxScene, + &CmndKnxTxCmnd, &CmndKnxTxVal, &CmndKnxEnabled, &CmndKnxEnhanced, + &CmndKnxPa, &CmndKnxGa, &CmndKnxCb, &CmndKnxTxScene, &CmndKnxTxFloat, &CmndKnxTxVal, &CmndKnxTxByte}; -#ifndef KNX_ENHANCEMENT_REPEAT -#define KNX_ENHANCEMENT_REPEAT 3 -#endif + address_t KNX_physs_addr; // Physical KNX address of this device + address_t KNX_addr; // KNX Address converter variable +struct Knx_t { + float last_temp; + float last_hum; + uint8_t toggle_inhibit; + bool started = false; +} Knx; + +/*********************************************************************************************/ void KNX_Send_1bit(address_t const &receiver, uint8_t value, knx_command_type_t ct) { @@ -324,6 +352,7 @@ void KNX_Send_6byte_color(address_t const &receiver, uint8_t* color, knx_command #define KNX_WRITE_6BYTE_COLOR(r,rgbw) KNX_Send_6byte_color((r),(rgbw),KNX_CT_WRITE) #define KNX_ANSWER_6BYTE_COLOR(r,rgbw) KNX_Send_6byte_color((r),(rgbw),KNX_CT_ANSWER) +/*********************************************************************************************/ uint8_t KNX_GA_Search( uint8_t param, uint8_t start = 0 ) { @@ -562,6 +591,7 @@ bool KNX_CONFIG_NOT_MATCH(void) return false; } +/*********************************************************************************************/ void KNXStart(void) { @@ -723,10 +753,10 @@ void KNX_CB_Action(message_t const &msg, void *arg) } else if (chan->type < 17) // Toggle Relays { - if (!toggle_inhibit) { + if (!Knx.toggle_inhibit) { ExecuteCommandPower((chan->type) -8, POWER_TOGGLE, SRC_KNX); if (Settings->flag.knx_enable_enhancement) { - toggle_inhibit = TOGGLE_INHIBIT_TIME; + Knx.toggle_inhibit = TOGGLE_INHIBIT_TIME; } } } @@ -735,7 +765,7 @@ void KNX_CB_Action(message_t const &msg, void *arg) else if (((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT5)) || ((chan->type >= KNX_SLOT6) && (chan->type <= KNX_SLOT9))) // KNX RX SLOTs (write command) { - if (!toggle_inhibit) { + if (!Knx.toggle_inhibit) { uint32_t slot_offset = KNX_SLOT1; if (chan->type >= KNX_SLOT6) { slot_offset = KNX_SLOT6; @@ -750,19 +780,19 @@ void KNX_CB_Action(message_t const &msg, void *arg) } ExecuteCommand(command, SRC_KNX); if (Settings->flag.knx_enable_enhancement) { - toggle_inhibit = TOGGLE_INHIBIT_TIME; + Knx.toggle_inhibit = TOGGLE_INHIBIT_TIME; } } } else if (chan->type == KNX_SCENE) // KNX RX SCENE SLOT (write command) { - if (!toggle_inhibit) { + if (!Knx.toggle_inhibit) { char command[25]; // Value received snprintf_P(command, sizeof(command), PSTR("event KNX_SCENE=%s"), tempchar); ExecuteCommand(command, SRC_KNX); if (Settings->flag.knx_enable_enhancement) { - toggle_inhibit = TOGGLE_INHIBIT_TIME; + Knx.toggle_inhibit = TOGGLE_INHIBIT_TIME; } } } @@ -770,25 +800,25 @@ void KNX_CB_Action(message_t const &msg, void *arg) #ifdef USE_LIGHT else if (chan->type == KNX_DIMMER) // KNX RX DIMMER SLOT (write command) { - if (!toggle_inhibit) { + if (!Knx.toggle_inhibit) { char command[25]; // Value received snprintf_P(command, sizeof(command), PSTR("Dimmer %s"), tempchar); ExecuteCommand(command, SRC_KNX); if (Settings->flag.knx_enable_enhancement) { - toggle_inhibit = TOGGLE_INHIBIT_TIME; + Knx.toggle_inhibit = TOGGLE_INHIBIT_TIME; } } } else if (chan->type == KNX_COLOUR) // KNX RX COLOUR_RGB/RGBW SLOT (write command) { - if (!toggle_inhibit) { + if (!Knx.toggle_inhibit) { char command[25]; // Value received snprintf_P(command, sizeof(command), PSTR("Color #%s"), tempchar); ExecuteCommand(command, SRC_KNX); if (Settings->flag.knx_enable_enhancement) { - toggle_inhibit = TOGGLE_INHIBIT_TIME; + Knx.toggle_inhibit = TOGGLE_INHIBIT_TIME; } } } @@ -801,17 +831,17 @@ void KNX_CB_Action(message_t const &msg, void *arg) else if (chan->type == KNX_TEMPERATURE) // Reply Temperature { #ifdef KNX_USE_DPT9 - KNX_ANSWER_2BYTE_FLOAT(msg.received_on, last_temp); + KNX_ANSWER_2BYTE_FLOAT(msg.received_on, Knx.last_temp); #else - KNX_ANSWER_4BYTE_FLOAT(msg.received_on, last_temp); + KNX_ANSWER_4BYTE_FLOAT(msg.received_on, Knx.last_temp); #endif // KNX_USE_DPT9 } else if (chan->type == KNX_HUMIDITY) // Reply Humidity { #ifdef KNX_USE_DPT9 - KNX_ANSWER_2BYTE_FLOAT(msg.received_on, last_hum); + KNX_ANSWER_2BYTE_FLOAT(msg.received_on, Knx.last_hum); #else - KNX_ANSWER_4BYTE_FLOAT(msg.received_on, last_hum); + KNX_ANSWER_4BYTE_FLOAT(msg.received_on, Knx.last_hum); #endif // KNX_USE_DPT9 } #if defined(USE_ENERGY_SENSOR) @@ -850,7 +880,7 @@ void KNX_CB_Action(message_t const &msg, void *arg) else if (((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT5)) || ((chan->type >= KNX_SLOT6) && (chan->type <= KNX_SLOT9))) // KNX RX SLOTs (read command) { - if (!toggle_inhibit) { + if (!Knx.toggle_inhibit) { uint32_t slot_offset = KNX_SLOT1; if (chan->type >= KNX_SLOT6) { slot_offset = KNX_SLOT6; @@ -859,7 +889,7 @@ void KNX_CB_Action(message_t const &msg, void *arg) snprintf_P(command, sizeof(command), PSTR("event KNXRX_REQ%d"), ((chan->type) - slot_offset + 1 ) ); ExecuteCommand(command, SRC_KNX); if (Settings->flag.knx_enable_enhancement) { - toggle_inhibit = TOGGLE_INHIBIT_TIME; + Knx.toggle_inhibit = TOGGLE_INHIBIT_TIME; } } } @@ -977,10 +1007,10 @@ void KnxSensor(uint8_t sensor_type, float value) { if (sensor_type == KNX_TEMPERATURE) { - last_temp = value; + Knx.last_temp = value; } else if (sensor_type == KNX_HUMIDITY) { - last_hum = value; + Knx.last_hum = value; } if (!(Settings->flag.knx_enabled)) { return; } @@ -1171,9 +1201,9 @@ void HandleKNXConfiguration(void) WSContentSend_P(HTTP_FORM_KNX2); for (uint32_t i = 0; i < KNX_MAX_device_param ; i++) { - if ( device_param[i].show ) + if ( device_param[knx_select_nice_list[i]].show ) { - WSContentSend_P(HTTP_FORM_KNX_OPT, device_param[i].type, device_param_ga[i]); + WSContentSend_P(HTTP_FORM_KNX_OPT, device_param[knx_select_nice_list[i]].type, device_param_ga[knx_select_nice_list[i]]); } } WSContentSend_P(PSTR(" -> ")); @@ -1198,9 +1228,9 @@ void HandleKNXConfiguration(void) // Check How many Relays are available and add: RelayX and TogleRelayX if ( (i > 8) && (i < 16) ) { j=i-8; } else { j=i; } if ( i == 8 ) { j = 0; } - if ( device_param[j].show ) + if ( device_param[knx_select_nice_list[j]].show ) { - WSContentSend_P(HTTP_FORM_KNX_OPT, device_param[i].type, device_param_cb[i]); + WSContentSend_P(HTTP_FORM_KNX_OPT, device_param[knx_select_nice_list[i]].type, device_param_cb[knx_select_nice_list[i]]); } } WSContentSend_P(PSTR(" ")); @@ -1276,6 +1306,7 @@ void KNX_Save_Settings(void) void CmndKnxTxCmnd(void) { + // KNX_WRITE_1BIT if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_KNXTX_CMNDS) && (XdrvMailbox.data_len > 0) && Settings->flag.knx_enabled) { // XdrvMailbox.index <- KNX SLOT to use // XdrvMailbox.payload <- data to send @@ -1297,6 +1328,7 @@ void CmndKnxTxCmnd(void) void CmndKnxTxVal(void) { + // KNX_WRITE_4BYTE_FLOAT if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_KNXTX_CMNDS) && (XdrvMailbox.data_len > 0) && Settings->flag.knx_enabled) { // XdrvMailbox.index <- KNX SLOT to use // XdrvMailbox.payload <- data to send @@ -1306,12 +1338,10 @@ void CmndKnxTxVal(void) KNX_addr.value = Settings->knx_GA_addr[i]; float tempvar = CharToFloat(XdrvMailbox.data); - dtostrfd(tempvar,2,XdrvMailbox.data); - KNX_WRITE_4BYTE_FLOAT(KNX_addr, tempvar); - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d/%d/%d"), - device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], XdrvMailbox.data, + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %2_f " D_SENT_TO " %d/%d/%d"), + device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], &tempvar, KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1], i + 1); @@ -1323,6 +1353,7 @@ void CmndKnxTxVal(void) void CmndKnxTxFloat(void) { + // KNX_WRITE_2BYTE_FLOAT if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_KNXTX_CMNDS) && (XdrvMailbox.data_len > 0) && Settings->flag.knx_enabled) { // XdrvMailbox.index <- KNX SLOT to use // XdrvMailbox.payload <- data to send @@ -1332,12 +1363,10 @@ void CmndKnxTxFloat(void) KNX_addr.value = Settings->knx_GA_addr[i]; float tempvar = CharToFloat(XdrvMailbox.data); - dtostrfd(tempvar,2,XdrvMailbox.data); - KNX_WRITE_2BYTE_FLOAT(KNX_addr, tempvar); - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d/%d/%d (2 bytes float)"), - device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], XdrvMailbox.data, + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %2_f " D_SENT_TO " %d/%d/%d (2 bytes float)"), + device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], &tempvar, KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1], i + 1); @@ -1348,6 +1377,7 @@ void CmndKnxTxFloat(void) void CmndKnxTxByte(void) { + // KNX_WRITE_1BYTE_UINT if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_KNXTX_CMNDS) && (XdrvMailbox.data_len > 0) && Settings->flag.knx_enabled) { // XdrvMailbox.index <- KNX SLOT to use // XdrvMailbox.payload <- data to send @@ -1357,12 +1387,10 @@ void CmndKnxTxByte(void) KNX_addr.value = Settings->knx_GA_addr[i]; uint8_t tempvar = TextToInt(XdrvMailbox.data); - dtostrfd(tempvar,0,XdrvMailbox.data); - KNX_WRITE_1BYTE_UINT(KNX_addr, tempvar); - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d/%d/%d (1 byte unsigned)"), - device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], XdrvMailbox.data, + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %d " D_SENT_TO " %d/%d/%d (1 byte unsigned)"), + device_param_ga[knx_slot_xref[XdrvMailbox.index -1] -1], tempvar, KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); i = KNX_GA_Search(knx_slot_xref[XdrvMailbox.index -1], i + 1); @@ -1380,12 +1408,10 @@ void CmndKnxTxScene(void) KNX_addr.value = Settings->knx_GA_addr[i]; uint8_t tempvar = TextToInt(XdrvMailbox.data); - dtostrfd(tempvar,0,XdrvMailbox.data); - KNX_WRITE_1BYTE_UINT(KNX_addr, tempvar); - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d/%d/%d"), - device_param_ga[KNX_SCENE-1], XdrvMailbox.data, + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %d " D_SENT_TO " %d/%d/%d"), + device_param_ga[KNX_SCENE-1], tempvar, KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); ResponseCmndIdxChar (XdrvMailbox.data); } @@ -1544,8 +1570,8 @@ bool Xdrv11(uint32_t function) if (!TasmotaGlobal.global_state.network_down) { knx.loop(); } // Process knx events break; case FUNC_EVERY_50_MSECOND: - if (toggle_inhibit) { - toggle_inhibit--; + if (Knx.toggle_inhibit) { + Knx.toggle_inhibit--; } break; case FUNC_ANY_KEY: @@ -1568,13 +1594,13 @@ bool Xdrv11(uint32_t function) KNX_INIT(); break; case FUNC_NETWORK_UP: - if (!knx_started && Settings->flag.knx_enabled) { // CMND_KNX_ENABLED + if (!Knx.started && Settings->flag.knx_enabled) { // CMND_KNX_ENABLED KNXStart(); - knx_started = true; + Knx.started = true; } break; case FUNC_NETWORK_DOWN: - knx_started = false; + Knx.started = false; break; // case FUNC_SET_POWER: // break; From 9317e02f25d8f67821dda11961d2c1a136c6b03b Mon Sep 17 00:00:00 2001 From: gemu Date: Thu, 5 Dec 2024 15:42:20 +0100 Subject: [PATCH 190/205] recode powerwall (#22589) --- tasmota/include/Powerwall.h | 400 +++++++++++++++--- .../tasmota_xdrv_driver/xdrv_10_scripter.ino | 92 ++-- 2 files changed, 387 insertions(+), 105 deletions(-) diff --git a/tasmota/include/Powerwall.h b/tasmota/include/Powerwall.h index e81c0ab5e..518d2dde4 100755 --- a/tasmota/include/Powerwall.h +++ b/tasmota/include/Powerwall.h @@ -1,17 +1,26 @@ -// inspred by https://github.com/MoritzLerch/tesla-pv-display +// inspired by https://github.com/MoritzLerch/tesla-pv-display #ifndef Powerwall_h #define Powerwall_h -// include libraries -#include "WiFiClientSecureLightBearSSL.h" + +#define PW_RETRIES 2 + +#define PWL_LOGLVL LOG_LEVEL_DEBUG + +// include libraries from email client +// standard ssl does not work at all +ESP_SSLClient ssl_client; +WiFiClientImpl basic_client; class Powerwall { private: - const char* powerwall_ip; + String powerwall_ip; String tesla_email; String tesla_password; String authCookie; + String cts1; + String cts2; public: Powerwall(); @@ -19,57 +28,132 @@ class Powerwall { String GetRequest(String url, String authCookie); String GetRequest(String url); String AuthCookie(); - void resetAuthCookie(); + String Pwl_test(String); }; +#ifndef POWERWALL_IP_CONFIG + #define POWERWALL_IP_CONFIG "192.168.188.60" +#endif + +#ifndef TESLA_EMAIL + #define TESLA_EMAIL "email" +#endif + +#ifndef TESLA_PASSWORD + #define TESLA_PASSWORD "password" +#endif + +#ifndef TESLA_POWERWALL_CTS1 + #define TESLA_POWERWALL_CTS1 "cts1" +#endif + +#ifndef TESLA_POWERWALL_CTS2 + #define TESLA_POWERWALL_CTS2 "cts2" +#endif + Powerwall::Powerwall() { powerwall_ip = POWERWALL_IP_CONFIG; tesla_email = TESLA_EMAIL; tesla_password = TESLA_PASSWORD; authCookie = ""; + cts1 = TESLA_POWERWALL_CTS1; + cts2 = TESLA_POWERWALL_CTS2; } String Powerwall::AuthCookie() { return authCookie; } -void Powerwall::resetAuthCookie() { - authCookie = ""; + +String Powerwall::Pwl_test(String ip) { + AddLog(PWL_LOGLVL, PSTR("PWL: try to open %s"), ip.c_str()); + + ssl_client.setInsecure(); + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(0); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + // For server that does not support SSL fragment size negotiation, leave this setting the default value + // by not set any buffer size or set the rx buffer size to maximum SSL record size (16384) and 512 for tx buffer size. + //ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client); + + int retry = 0; + while (retry < PW_RETRIES) { + int32_t res = ssl_client.connect(ip.c_str(), 443); + if (res) { + break; + } + delay(100); + retry++; + } + + if (retry >= PW_RETRIES) { + AddLog(PWL_LOGLVL, PSTR("PWL: failed")); + } else { + AddLog(PWL_LOGLVL, PSTR("PWL: connected")); + } + + ssl_client.stop(); + + return "\n"; } + +void pHexdump(uint8_t *sbuff, uint32_t slen) { + char cbuff[slen*3+10]; + char *cp = cbuff; + *cp++ = '>'; + *cp++ = ' '; + for (uint32_t cnt = 0; cnt < slen; cnt ++) { + sprintf_P(cp, PSTR("%02x "), sbuff[cnt]); + cp += 3; + } + AddLog(PWL_LOGLVL, PSTR("PWL: response: %s"), cbuff); + +} + + /** * This function returns a string with the authToken based on the basic login endpoint of * the powerwall in combination with the credentials from the secrets.h * @returns authToken to be used in an authCookie */ String Powerwall::getAuthCookie() { - AddLog(LOG_LEVEL_DEBUG, PSTR("PWL: requesting new auth Cookie from %s"), powerwall_ip); + AddLog(PWL_LOGLVL, PSTR("PWL: requesting new auth Cookie from %s"), powerwall_ip.c_str()); String apiLoginURL = "/api/login/Basic"; -#ifdef ESP32 - WiFiClientSecure *httpsClient = new WiFiClientSecure; -#else - // BearSSL::WiFiClientSecure_light *httpsClient = new BearSSL::WiFiClientSecure_light(1024,1024); - WiFiClientSecure *httpsClient = new WiFiClientSecure; -#endif - httpsClient->setInsecure(); - httpsClient->setTimeout(10000); + ssl_client.setInsecure(); + //ssl_client.setBufferSizes(4096 /* rx */, 512 /* tx */); + ssl_client.setTimeout(3000); + ssl_client.setClient(&basic_client); + ssl_client.setDebugLevel(3); int retry = 0; - -#define PW_RETRIES 5 - while ((!httpsClient->connect(powerwall_ip, 443)) && (retry < PW_RETRIES)) { + while (retry < PW_RETRIES) { + int32_t res = ssl_client.connect(powerwall_ip.c_str(), 443); + if (res) { + break; + } delay(100); - Serial.print("."); retry++; } if (retry >= PW_RETRIES) { - delete httpsClient; return ("CONN-FAIL"); } - AddLog(LOG_LEVEL_DEBUG, PSTR("PWL: connected")); + AddLog(PWL_LOGLVL, PSTR("PWL: connected")); String dataString = "{\"username\":\"customer\",\"email\":\"" + tesla_email + "\",\"password\":\"" + tesla_password + "\",\"force_sm_off\":false}"; @@ -80,31 +164,113 @@ String Powerwall::getAuthCookie() { "Content-Length: " + dataString.length() + "\r\n" + "\r\n" + dataString + "\r\n\r\n"; - httpsClient->println(payload); + AddLog(PWL_LOGLVL, PSTR("PWL: payload: %s"),payload.c_str()); - while (httpsClient->connected()) { - String response = httpsClient->readStringUntil('\n'); - if (response == "\r") { - break; + ssl_client.println(payload); + + uint8_t flag = 0; + + uint8_t string[1200]; + uint32_t dlen; + uint32_t timeout = 30; + while (ssl_client.connected()) { + if (ssl_client.available()) { + dlen = ssl_client.available(); + AddLog(PWL_LOGLVL, PSTR("PWL: available: %d"), dlen); + String response = ""; +#if 1 + if (!flag) { + char c = ssl_client.peek(); + AddLog(PWL_LOGLVL, PSTR("PWL: peek: %c"), c); + if (c != 'H') { + AddLog(PWL_LOGLVL, PSTR("PWL: wrong response: %c"), c); + ssl_client.stop(); + return ""; + } else { + //basic_client.read(string, 17); + //ssl_client.read(string, 17); + const char *cp = ssl_client.peekBuffer(); + //ssl_client.peekBytes(string, 17); + //ssl_client.peekConsume(17); + //string[17] = 0; + //pHexdump(string, 17); + AddLog(PWL_LOGLVL, PSTR("PWL: 1. response: %s"), cp); + cp = strchr(cp, '{'); + if (cp) { + char *cp1 = strchr(cp, '}'); + if (cp1) { + *(cp1 + 1) = 0; + AddLog(PWL_LOGLVL, PSTR("PWL: json: %s"), cp); + char str_value[256]; + str_value[0] = 0; + float fv; + JsonParser parser((char*)cp); + JsonParserObject obj = parser.getRootObject(); + uint32_t res = JsonParsePath(&obj, "token", '#', &fv, str_value, sizeof(str_value)); + + AddLog(PWL_LOGLVL, PSTR("PWL: token: %s"), str_value); + + ssl_client.stop(); + return str_value; + } + } + } + flag = 1; + } + response = ssl_client.readStringUntil('\n'); + AddLog(PWL_LOGLVL, PSTR("PWL: response: %s"), response.c_str()); + #else + ssl_client.read(string, dlen); + pHexdump(string, dlen); + #endif + char *cp = (char*)response.c_str(); + if (!strncmp_P(cp, PSTR("HTTP"), 4)) { + char *sp = strchr(cp, ' '); + if (sp) { + sp++; + uint16_t result = strtol(sp, 0, 10); + if (result != 200) { + ssl_client.stop(); + return ""; + } else { + // break; + } + } + } + if (response == "\r") { + break; + } + } + timeout--; + delay(100); + AddLog(PWL_LOGLVL, PSTR("PWL: timeout: %d"), timeout); + if (!timeout) { + ssl_client.stop(); + return ""; } } - String jsonInput = httpsClient->readStringUntil('\n'); + String jsonInput; + dlen = ssl_client.available(); + if (ssl_client.connected() && dlen) { + ssl_client.read(string, dlen); + string[dlen] = 0; + jsonInput = (char*)string; + AddLog(PWL_LOGLVL, PSTR("PWL: jsonInput %s"),jsonInput.c_str()); + } - char str_value[128]; + char str_value[256]; str_value[0] = 0; float fv; JsonParser parser((char*)jsonInput.c_str()); JsonParserObject obj = parser.getRootObject(); uint32_t res = JsonParsePath(&obj, "token", '#', &fv, str_value, sizeof(str_value)); - AddLog(LOG_LEVEL_DEBUG, PSTR("PWL: token: %s"), str_value); + AddLog(PWL_LOGLVL, PSTR("PWL: token: %s"), str_value); - authCookie = str_value; - - delete httpsClient; + ssl_client.stop(); - return authCookie; + return str_value; } /** @@ -117,64 +283,138 @@ String Powerwall::getAuthCookie() { * @param authCookie optional, but recommended * @returns content of request */ -String Powerwall::GetRequest(String url, String authCookie) { -#ifdef ESP32 - WiFiClientSecure *httpsClient = new WiFiClientSecure; -#else - //BearSSL::WiFiClientSecure_light *httpsClient = new BearSSL::WiFiClientSecure_light(1024,1024); - WiFiClientSecure *httpsClient = new WiFiClientSecure; -#endif - httpsClient->setInsecure(); - httpsClient->setTimeout(10000); +String Powerwall::GetRequest(String url, String in_authCookie) { - if (authCookie == "") { - getAuthCookie(); + + AddLog(PWL_LOGLVL, PSTR("PWL: cookie %s"), in_authCookie.c_str()); + + ssl_client.setInsecure(); + ssl_client.setTimeout(5000); + ssl_client.setClient(&basic_client); + //ssl_client.setBufferSizes(4096 /* rx */, 512 /* tx */); + ssl_client.setBufferSizes(16384, 512); + + + if (in_authCookie == "") { + authCookie = getAuthCookie(); } - AddLog(LOG_LEVEL_DEBUG, PSTR("PWL: doing GET-request to %s%s"), powerwall_ip, url.c_str()); + AddLog(PWL_LOGLVL, PSTR("PWL: doing GET-request to %s - %s"), powerwall_ip.c_str(), url.c_str()); int retry = 0; - while ((!httpsClient->connect(powerwall_ip, 443)) && (retry < 15)) { + while ((!ssl_client.connect(powerwall_ip.c_str(), 443)) && (retry < PW_RETRIES)) { delay(100); - Serial.print("."); + //Serial.print("."); retry++; } - if (retry >= 15) { - delete httpsClient; + if (retry >= PW_RETRIES) { return ("CONN-FAIL"); } + AddLog(PWL_LOGLVL, PSTR("PWL: connected")); + // HTTP/1.0 is used because of Chunked transfer encoding - httpsClient->print(String("GET ") + url + " HTTP/1.0" + "\r\n" + + String request = "GET " + url + " HTTP/1.0" + "\r\n" + "Host: " + powerwall_ip + "\r\n" + "Cookie: " + "AuthCookie" + "=" + authCookie + "\r\n" + - "Connection: close\r\n\r\n"); + "Connection: close\r\n\r\n"; + + ssl_client.println(request); + + AddLog(PWL_LOGLVL, PSTR("PWL: request: %s"), request.c_str()); - while (httpsClient->connected()) { - String response = httpsClient->readStringUntil('\n'); - char *cp = (char*)response.c_str(); - if (!strncmp_P(cp, PSTR("HTTP"), 4)) { - char *sp = strchr(cp, ' '); - if (sp) { - sp++; - uint16_t result = strtol(sp, 0, 10); - AddLog(LOG_LEVEL_DEBUG, PSTR("PWL: result %d"), result); - // in case of error 401, get new cookie - if (result == 401) { - authCookie = ""; - resetAuthCookie(); + uint32_t timeout = 500; + int32_t chunked = 0; + while (ssl_client.connected()) { + if (ssl_client.available()) { + String response = ssl_client.readStringUntil('\n'); + AddLog(PWL_LOGLVL, PSTR("PWL: result %s"), response.c_str()); + if (chunked == -2) { + // process chunc size + chunked = strtol(response.c_str(), 0, 16); + AddLog(PWL_LOGLVL, PSTR("PWL: chunc size %d"), chunked); + break; + } + char *cp = (char*)response.c_str(); + if (!strncmp_P(cp, PSTR("HTTP"), 4)) { + char *sp = strchr(cp, ' '); + if (sp) { + sp++; + uint16_t result = strtol(sp, 0, 10); + AddLog(PWL_LOGLVL, PSTR("PWL: result %d"), result); + // in case of error 401, get new cookie + if (result == 401) { + authCookie = ""; + } else if (result != 200) { + ssl_client.stop(); + return "\n"; + } + } + } + if (!strncmp_P(cp, PSTR("Transfer-Encoding: chunked"), 26)) { + chunked = -1; + AddLog(PWL_LOGLVL, PSTR("PWL: chunked %d"), chunked); + } + + if (response == "\r") { + if (chunked) { + // skip + chunked = -2; + } else { + break; } } } - if (response == "\r") { + timeout--; + delay(10); + if (!timeout) { break; } } - String result = httpsClient->readStringUntil('\n'); - delete httpsClient; + String result = "\r"; + + timeout = 100; + char *string = (char*)calloc(4096,1); + if (string) { + char *cp = string; + while (ssl_client.connected()) { + uint16_t dlen; + dlen = ssl_client.available(); + if (dlen) { + ssl_client.read((uint8_t*)cp, dlen); + cp += dlen; + *cp = 0; + } + delay(10); + timeout--; + if (!timeout) { + break; + } + } + AddLog(PWL_LOGLVL, PSTR("PWL: result %s"), string); + result = string; + free(string); + } + ssl_client.stop(); + + // custom replace + result.replace(cts1, "PW_CTS1"); + + result.replace(cts2, "PW_CTS2"); + + // shrink data size because it exceeds json parser maxsize + result.replace("communication_time", "ct"); + result.replace("instant", "i"); + result.replace("apparent", "a"); + result.replace("reactive", "r"); + + result.replace("nominal_full_pack_energy", "f_p_e"); + result.replace("nominal_energy_remaining", "n_e_r"); + result.replace("backup_reserve_percent", "b_r_p"); + return result; } @@ -182,6 +422,30 @@ String Powerwall::GetRequest(String url, String authCookie) { * this is getting called if there was no provided authCookie in powerwallGetRequest(String url, String authCookie) */ String Powerwall::GetRequest(String url) { + if (url[0] == '@') { + if (url[1] == 'D') { + // define vars + //AddLog(PWL_LOGLVL, PSTR("PWL: %s - %s - %s"), powerwall_ip.c_str(), tesla_email.c_str(), tesla_password.c_str()); + url = url.substring(2); + uint16_t pos = strcspn(url.c_str(), ","); + powerwall_ip = url.substring(0, pos); + url = url.substring(pos + 1); + pos = strcspn(url.c_str(), ","); + tesla_email = url.substring(0, pos); + tesla_password = url.substring(pos + 1); + //AddLog(PWL_LOGLVL, PSTR("PWL: %s - %s - %s"), powerwall_ip.c_str(), tesla_email.c_str(), tesla_password.c_str()); + return ""; + } if (url[1] == 'C') { + url = url.substring(2); + uint16_t pos = strcspn(url.c_str(), ","); + cts1 = url.substring(0, pos); + cts2 = url.substring(pos + 1); + return ""; + } else { + url = url.substring(1); + return Pwl_test(url); + } + } return (GetRequest(url, getAuthCookie())); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino index 254f03e10..636c163df 100755 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino @@ -352,6 +352,7 @@ void alt_eeprom_readBytes(uint32_t adr, uint32_t len, uint8_t *buf) { #include #ifdef TESLA_POWERWALL +#include "SSLClient/ESP_SSLClient.h" #include "include/powerwall.h" #endif @@ -773,7 +774,7 @@ typedef struct { SCRIPT_MEM glob_script_mem; -uint32_t Plugin_Query(uint16_t, uint8_t); +uint32_t Plugin_Query(uint16_t, uint8_t, char *); void script_setaflg(uint8_t flg) { glob_script_mem.tasm_cmd_activ = flg; @@ -845,8 +846,8 @@ int32_t play_wave(char *path); #if defined(USE_BINPLUGINS) && !defined(USE_SML_M) SML_TABLE *get_sml_table(void) { - if (Plugin_Query(53, 0)) { - return (SML_TABLE*)Plugin_Query(53, 1); + if (Plugin_Query(53, 0, 0)) { + return (SML_TABLE*)Plugin_Query(53, 1, 0); } else { return 0; } @@ -2585,19 +2586,23 @@ uint32_t match_vars(char *dvnam, TS_FLOAT **fp, char **sp, uint32_t *ind) { if (slen == olen && *cp == dvnam[0]) { if (!strncmp(cp, dvnam, olen)) { uint16_t index = vtp[count].index; - if (vtp[count].bits.is_string == 0) { - if (vtp[count].bits.is_filter) { - // error - return 0; + if (vtp[count].bits.global > 0) { + if (vtp[count].bits.is_string == 0) { + if (vtp[count].bits.is_filter) { + // error + return 0; + } else { + *fp = &glob_script_mem.fvars[index]; + *ind = count; + return NUM_RES; + } } else { - *fp = &glob_script_mem.fvars[index]; + *sp = glob_script_mem.glob_snp + (index * glob_script_mem.max_ssize); *ind = count; - return NUM_RES; + return STR_RES; } } else { - *sp = glob_script_mem.glob_snp + (index * glob_script_mem.max_ssize); - *ind = count; - return STR_RES; + return 0; } } } @@ -2839,15 +2844,15 @@ char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, TS_FLOAT *fp, char * } const char *term="\n\r ])=+-/*%>4095) { AddLog(LOG_LEVEL_INFO, PSTR("PWL: result overflow: %d"), result.length()); } @@ -13160,9 +13171,16 @@ uint32_t script_i2c(uint8_t sel, uint16_t val, uint32_t val1) { switch (sel) { case 0: glob_script_mem.script_i2c_addr = val; -#if defined(ESP32) && defined(USE_I2C_BUS2) +#ifdef ESP32 if (val1 == 0) glob_script_mem.script_i2c_wire = &Wire; - else glob_script_mem.script_i2c_wire = &Wire1; + else { +#if defined(USE_I2C_BUS2) + glob_script_mem.script_i2c_wire = &Wire1; +#else + glob_script_mem.script_i2c_wire = &Wire; +#endif + } + #else glob_script_mem.script_i2c_wire = &Wire; #endif From f341f8d35aef94bad5fdde1f444e0e69174231c7 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:48:05 +0100 Subject: [PATCH 191/205] =?UTF-8?q?language=20(DE):=20shorten=20(Men=C3=BC?= =?UTF-8?q?)=20Texts=20(#22594)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * language (DE): shorten (Menü) Texts * KNX: einmalig -> eindeutig --- tasmota/language/de_DE.h | 150 +++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 04096ee3c..78daae494 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -259,18 +259,18 @@ #define D_NOSCRIPT "JavaScript aktivieren um Tasmota benutzen zu können" #define D_SAFEBOOT "SAFEBOOT" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMUM-Firmware
bitte upgraden" -#define D_WEBSERVER_ACTIVE_ON "Webserver aktiv bei" +#define D_WEBSERVER_ACTIVE_ON "Webserver aktiv" #define D_WITH_IP_ADDRESS "mit IP-Adresse" #define D_WEBSERVER_STOPPED "Webserver angehalten" #define D_FILE_NOT_FOUND "Datei nicht gefunden" #define D_REDIRECTED "umgeleitet zum Captive Portal" #define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "WLAN-Manager AccessPoint gesetzt und behält Station" #define D_WIFIMANAGER_SET_ACCESSPOINT "WLAN-Manager AccessPoint gesetzt" -#define D_TRYING_TO_CONNECT "Versuche mit Netzwerk zu verbinden" +#define D_TRYING_TO_CONNECT "Verbindungsversuch mit Netzwerk" #define D_RESTART_IN "Neustart in" #define D_SECONDS "Sekunden" -#define D_DEVICE_WILL_RESTART "Gerät wird jetzt neu gestartet" +#define D_DEVICE_WILL_RESTART "Neustart" #define D_BUTTON_TOGGLE "An/Aus" #define D_CONFIGURATION "Einstellungen" #define D_INFORMATION "Informationen" @@ -280,68 +280,68 @@ #define D_CONSOLE "Konsole" #define D_CONFIRM_RESTART "Wirklich neustarten?" -#define D_CONFIGURE_MODULE "Geräteeinstellungen" -#define D_CONFIGURE_WIFI "WLAN-Einstellungen" -#define D_CONFIGURE_MQTT "MQTT-Einstellungen" -#define D_CONFIGURE_DOMOTICZ "Domoticz-Einstellungen" -#define D_CONFIGURE_LOGGING "Logging-Einstellungen" -#define D_CONFIGURE_OTHER "Weitere Einstellungen" -#define D_CONFIRM_RESET_CONFIGURATION "Zurücksetzen der Konfiguration bestätigen" -#define D_RESET_CONFIGURATION "Konfiguration zurücksetzen" -#define D_BACKUP_CONFIGURATION "Konfiguration sichern" -#define D_RESTORE_CONFIGURATION "Konfiguration wiederherstellen" +#define D_CONFIGURE_MODULE "Gerät" +#define D_CONFIGURE_WIFI "WLAN" +#define D_CONFIGURE_MQTT "MQTT" +#define D_CONFIGURE_DOMOTICZ "Domoticz" +#define D_CONFIGURE_LOGGING "Logging" +#define D_CONFIGURE_OTHER "Weitere" +#define D_CONFIRM_RESET_CONFIGURATION "Zurücksetzen bestätigen" +#define D_RESET_CONFIGURATION "Zurücksetzen" +#define D_BACKUP_CONFIGURATION "Sichern" +#define D_RESTORE_CONFIGURATION "Wiederherstellen" #define D_START_RESTORE "Wiederherstellung starten" #define D_MAIN_MENU "Hauptmenü" -#define D_MODULE_PARAMETERS "Geräteeinstellungen" -#define D_MODULE_TYPE "Gerätetyp" +#define D_MODULE_PARAMETERS "Parameter" +#define D_MODULE_TYPE "Typ" #define D_PULLUP_ENABLE "Pull-up aktiv" #define D_ADC "ADC" #define D_GPIO "GPIO" #define D_SERIAL_IN "serieller Eingang [serial in]" #define D_SERIAL_OUT "serieller Ausgang [serial out]" -#define D_WIFI_PARAMETERS "WLAN-Einstellungen" -#define D_SCAN_FOR_WIFI_NETWORKS "WLAN-Netzwerk suchen und auswählen" +#define D_WIFI_PARAMETERS "WLAN" +#define D_SCAN_FOR_WIFI_NETWORKS "WLAN suchen" #define D_SCAN_DONE "Suche abgeschlossen" #define D_NO_NETWORKS_FOUND "Kein Netzwerk gefunden" #define D_REFRESH_TO_SCAN_AGAIN "Aktualisieren, um erneut zu suchen" #define D_DUPLICATE_ACCESSPOINT "AccessPoint duplizieren" -#define D_SKIPPING_LOW_QUALITY "überspringe wegen niedriger Qualität" +#define D_SKIPPING_LOW_QUALITY "WLAN Signal zu schwach" #define D_MODE "Mode" #define D_RSSI "RSSI" #define D_WEP "WEP" #define D_WPA_PSK "WPA-PSK" #define D_WPA2_PSK "WPA2-PSK" #define D_AP1_SSID "WLAN 1 - SSID" -#define D_AP1_SSID_HELP "WiFi Netzwerk auswählen oder eingeben" +#define D_AP1_SSID_HELP "WLAN auswählen oder eingeben" #define D_AP2_SSID "WLAN 2 - SSID" -#define D_AP2_SSID_HELP "alternatives WiFi Netzwerk eingeben" -#define D_AP_PASSWORD "WLAN - Passwort" -#define D_AP_PASSWORD_HELP "WiFi Passwort eingeben" -#define D_SELECT_YOUR_WIFI_NETWORK "WiFi Netzwerk auswählen" -#define D_SHOW_MORE_WIFI_NETWORKS "Suche nach WiFi Netzwerken" +#define D_AP2_SSID_HELP "alternatives WLAN" +#define D_AP_PASSWORD "Passwort" +#define D_AP_PASSWORD_HELP "Passwort eingeben" +#define D_SELECT_YOUR_WIFI_NETWORK "WLAN auswählen" +#define D_SHOW_MORE_WIFI_NETWORKS "Suche nach WLAN" #define D_SHOW_MORE_OPTIONS "Mehr Optionen" -#define D_CHECK_CREDENTIALS "Bitte SSID/Passwort überprüfen" -#define D_SUCCESSFUL_WIFI_CONNECTION "mit Wifi verbunden" -#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Das Fenster kann geschlossen werden" -#define D_REDIRECTING_TO_NEW_IP "Umleitung zur neuen Geräte IP-Adresse" +#define D_CHECK_CREDENTIALS "Bitte SSID/Passwort prüfen" +#define D_SUCCESSFUL_WIFI_CONNECTION "mit WLAN verbunden" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Bitte Fenster schließen" +#define D_REDIRECTING_TO_NEW_IP "Umleitung zur IP-Adresse" -#define D_MQTT_PARAMETERS "MQTT-Einstellungen" +#define D_MQTT_PARAMETERS "MQTT" #define D_CLIENT "Client" #define D_FULL_TOPIC "Full Topic" -#define D_LOGGING_PARAMETERS "Logging-Einstellungen" -#define D_SERIAL_LOG_LEVEL "Seriell-Log Level" -#define D_MQTT_LOG_LEVEL "MQTT-Log Level" -#define D_WEB_LOG_LEVEL "Web-Log Level" -#define D_SYS_LOG_LEVEL "Syslog Level" +#define D_LOGGING_PARAMETERS "Logging" +#define D_SERIAL_LOG_LEVEL "Seriell" +#define D_MQTT_LOG_LEVEL "MQTT" +#define D_WEB_LOG_LEVEL "Web" +#define D_SYS_LOG_LEVEL "Syslog" #define D_MORE_DEBUG "Mehr Details" #define D_SYSLOG_HOST "Syslog Host" #define D_SYSLOG_PORT "Syslog Port" #define D_TELEMETRY_PERIOD "Telemetrieperiode" -#define D_OTHER_PARAMETERS "Weitere Einstellungen" +#define D_OTHER_PARAMETERS "Weitere" #define D_TEMPLATE "Vorlage" #define D_ACTIVATE "Aktivieren" #define D_DEVICE_NAME "Gerätename" @@ -356,29 +356,29 @@ #define D_SINGLE_DEVICE "Einzelnes Gerät" #define D_MULTI_DEVICE "Mehrfachgerät" -#define D_CONFIGURE_TEMPLATE "Vorlage konfigurieren" -#define D_TEMPLATE_PARAMETERS "Vorlage Parameter" +#define D_CONFIGURE_TEMPLATE "konfigurieren" +#define D_TEMPLATE_PARAMETERS "Parameter" #define D_TEMPLATE_NAME "Name" #define D_BASE_TYPE "basiert auf" #define D_TEMPLATE_FLAGS "Optionen" -#define D_SAVE_CONFIGURATION "Konfiguration speichern" -#define D_CONFIGURATION_SAVED "Konfiguration gespeichert" -#define D_CONFIGURATION_RESET "Konfiguration zurücksetzen" +#define D_SAVE_CONFIGURATION "speichern" +#define D_CONFIGURATION_SAVED "gespeichert" +#define D_CONFIGURATION_RESET "zurücksetzen" #define D_PROGRAM_VERSION "Tasmota Version" -#define D_BUILD_DATE_AND_TIME "Erstellungszeitpunkt" +#define D_BUILD_DATE_AND_TIME "Erstellt" #define D_CORE_AND_SDK_VERSION "Core-/SDK-Version" -#define D_FLASH_WRITE_COUNT "Flash-Schreibzyklen" +#define D_FLASH_WRITE_COUNT "Schreibzyklen" #define D_MAC_ADDRESS "MAC-Adresse" -#define D_MQTT_HOST "MQTT Host" -#define D_MQTT_PORT "MQTT Port" -#define D_MQTT_CLIENT "MQTT Client" -#define D_MQTT_USER "MQTT Benutzer" -#define D_MQTT_TOPIC "MQTT Topic" -#define D_MQTT_GROUP_TOPIC "MQTT Group Topic" -#define D_MQTT_FULL_TOPIC "MQTT Full Topic" -#define D_MQTT_NO_RETAIN "MQTT No Retain" +#define D_MQTT_HOST "Host" +#define D_MQTT_PORT "Port" +#define D_MQTT_CLIENT "Client" +#define D_MQTT_USER "Benutzer" +#define D_MQTT_TOPIC "Topic" +#define D_MQTT_GROUP_TOPIC "Group Topic" +#define D_MQTT_FULL_TOPIC "Full Topic" +#define D_MQTT_NO_RETAIN "No Retain" #define D_MDNS_DISCOVERY "mDNS-Erkennung" #define D_MDNS_ADVERTISE "mDNS-Freigaben" #define D_ESP_CHIP_ID "ESP Chip ID" @@ -388,7 +388,7 @@ #define D_UPGRADE_BY_WEBSERVER "Update über Webserver" #define D_OTA_URL "OTA-URL" -#define D_START_UPGRADE "Update starten" +#define D_START_UPGRADE "starten" #define D_UPGRADE_BY_FILE_UPLOAD "Update Datei hochladen" #define D_UPLOAD_FACTORY "Wechsle zur Safeboot Partition" #define D_UPLOAD_STARTED "Upload gestartet" @@ -401,7 +401,7 @@ #define D_UPLOAD_ERR_3 "Falsche Dateisignatur" #define D_UPLOAD_ERR_4 "Datei überschreitet vorhdn․ Flashspeicher" #define D_UPLOAD_ERR_5 "Upload Buffer Vergleich weicht ab" -#define D_UPLOAD_ERR_6 "Upload fehlgeschlagen․ Aktiviere Logging 3" +#define D_UPLOAD_ERR_6 "Upload fehlgeschlagen․ Details mit Logging 3" #define D_UPLOAD_ERR_7 "Upload abgebrochen" #define D_UPLOAD_ERR_8 "Datei ungültig" #define D_UPLOAD_ERR_9 "Datei zu groß" @@ -417,8 +417,8 @@ #define D_NEED_USER_AND_PASSWORD "Benötige user=&password=" // xdrv_01_mqtt.ino -#define D_FINGERPRINT "TLS-Fingerabdruck wird verifiziert…" -#define D_TLS_CONNECT_FAILED_TO "TLS-Verbindung fehlgeschlagen an" +#define D_FINGERPRINT "TLS-Fingerabdruck wird verifiziert" +#define D_TLS_CONNECT_FAILED_TO "TLS-Verbindung fehlgeschlagen" #define D_RETRY_IN "Erneuter Versuch in" #define D_VERIFIED "verifiziert mit Fingerabdruck" #define D_INSECURE "unsichere Verbindung aufgrund ungültigen Fingerabdrucks" @@ -445,7 +445,7 @@ #define D_3_RESPONSE_PACKETS_SENT "3 Antwortpakete gesendet" // xdrv_07_domoticz.ino -#define D_DOMOTICZ_PARAMETERS "Domoticz-Einstellungen" +#define D_DOMOTICZ_PARAMETERS "Domoticz" #define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key Idx" #define D_DOMOTICZ_SWITCH_IDX "Switch Idx" @@ -463,8 +463,8 @@ #define D_DOMOTICZ_UPDATE_TIMER "Zeitplan-Update" // xdrv_09_timers.ino -#define D_CONFIGURE_TIMER "Zeitplaneinstellungen" -#define D_TIMER_PARAMETERS "Zeitplaneinstellungen" +#define D_CONFIGURE_TIMER "Zeitplan" +#define D_TIMER_PARAMETERS "Zeitplan" #define D_TIMER_ENABLE "Zeitpläne aktivieren" #define D_TIMER_ARM "Aktiv" #define D_TIMER_TIME "Uhrzeit" @@ -474,12 +474,12 @@ #define D_TIMER_ACTION "Aktion" // xdrv_10_knx.ino -#define D_CONFIGURE_KNX "KNX-Einstellungen" -#define D_KNX_PARAMETERS "KNX-Parameter" +#define D_CONFIGURE_KNX "KNX" +#define D_KNX_PARAMETERS "Parameter" #define D_KNX_GENERAL_CONFIG "Allgemein" #define D_KNX_PHYSICAL_ADDRESS "Physikalische Adresse" -#define D_KNX_PHYSICAL_ADDRESS_NOTE "(Muss einmalig im KNX-Netzwerk sein)" -#define D_KNX_ENABLE "KNX aktivieren" +#define D_KNX_PHYSICAL_ADDRESS_NOTE "Muss eindeutig im KNX-Netzwerk sein" +#define D_KNX_ENABLE "aktivieren" #define D_KNX_GROUP_ADDRESS_TO_WRITE "Daten zum Senden an Gruppenadresse" #define D_ADD "Hinzufügen" #define D_DELETE "Löschen" @@ -490,7 +490,7 @@ #define D_KNX_COMMAND_READ "Lesen" #define D_KNX_COMMAND_OTHER "Andere" #define D_SENT_TO "gesendet an" -#define D_KNX_WARNING "Die Gruppenadresse (0/0/0) ist reserviert und kann nicht verwendet werden" +#define D_KNX_WARNING "Die Gruppenadresse (0/0/0) ist reserviert" #define D_KNX_ENHANCEMENT "Erweiterte Kommunikation" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" @@ -498,15 +498,15 @@ #define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_23_zigbee -#define D_ZIGBEE_PERMITJOIN_ACTIVE "Gerätekopplung erlaubt" -#define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee Karte" +#define D_ZIGBEE_PERMITJOIN_ACTIVE "Kopplung erlaubt" +#define D_ZIGBEE_MAPPING_TITLE "Zigbee Karte" #define D_ZIGBEE_NOT_STARTED "Zigbee nicht gestartet" #define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "Karte in Erstellung (%d s․ verbleibend)" #define D_ZIGBEE_MAPPING_NOT_PRESENT "Keine Karte" -#define D_ZIGBEE_MAP_REFRESH "Zigbee Karte erneuern" -#define D_ZIGBEE_MAP "Zigbee Karte" -#define D_ZIGBEE_PERMITJOIN "Zigbee Kopplung ein" -#define D_ZIGBEE_GENERATE_KEY "Erzeuge zufälligen Zigbee Netzwerkschlüssel" +#define D_ZIGBEE_MAP_REFRESH "Karte erneuern" +#define D_ZIGBEE_MAP "Karte" +#define D_ZIGBEE_PERMITJOIN "Kopplung ein" +#define D_ZIGBEE_GENERATE_KEY "Erzeuge zufälligen Netzwerkschlüssel" #define D_ZIGBEE_UNKNOWN_DEVICE "Unbekanntes Gerät" #define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unbekanntes Attribut" #define D_ZIGBEE_UNKNOWN_ENDPOINT "Unkbekannter Endpunkt" @@ -516,19 +516,19 @@ #define D_ZIGBEE_TOO_MANY_CLUSTERS "Nur eine Cluster-ID pro Kommando" #define D_ZIGBEE_CONFLICTING_ENDPOINTS "Kollidierende Endpunkte" #define D_ZIGBEE_WRONG_DELIMITER "Falscher Delimeter für Payload" -#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unerkanntes Zigbee Kommando: %s" +#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unerkanntes Kommando: %s" #define D_ZIGBEE_TOO_MANY_COMMANDS "Nur 1 Kommando zulässig (%d)" #define D_ZIGBEE_NO_ATTRIBUTE "Kein Attribut in der Liste" #define D_ZIGBEE_UNSUPPORTED_ATTRIBUTE_TYPE "Nicht unterstützter Attributtyp" #define D_ZIGBEE_JSON_REQUIRED "Konfiguration muss JSON-basiert sein" #define D_ZIGBEE_RESET_1_OR_2 "1 oder 2 für Reset" -#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gefunden an Adresse" -#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zufällige Zigbee Parameter erstellt, Überprüfung mit 'ZbConfig'" +#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM gefunden an Adresse" +#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zufällige Parameter erstellt, Überprüfung mit 'ZbConfig'" // xdrv_89_dali.ino #define D_SENSOR_DALI_RX "Dali RX" #define D_SENSOR_DALI_TX "Dali TX" -#define D_CONFIGURE_DALI "DALI-Einstellungen" +#define D_CONFIGURE_DALI "Dali Einstellungen" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energie heute" @@ -571,9 +571,9 @@ #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" // xdrv_79_esp32_ble.ino -#define D_CONFIGURE_BLE "BLE-Einstellungen" -#define D_BLE_PARAMETERS "Bluetooth-Einstellungen" -#define D_MQTT_BLE_ENABLE "Bluetooth aktivieren" +#define D_CONFIGURE_BLE "BLE Einstellungen" +#define D_BLE_PARAMETERS "BLE Parameter" +#define D_MQTT_BLE_ENABLE "BLE aktivieren" #define D_MQTT_BLE_ACTIVESCAN "Aktiv scannen (*)" #define D_BLE_DEVICES "Erkannte Geräte" #define D_BLE_REMARK "Mit (*) markierte Geräte werden nicht gespeichert." From 4ffc53b46561b700293be4fdbb83a4c7872327ad Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:02:44 +0100 Subject: [PATCH 192/205] Shorten menus and add submenu headers (#22592) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/language/af_AF.h | 34 +++++++++--------- tasmota/language/en_GB.h | 36 +++++++++---------- .../xdrv_01_9_webserver.ino | 8 +++++ 5 files changed, 45 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1beab31d1..81eb1c5ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ All notable changes to this project will be documented in this file. - Shutter wrong power ON state (#22548) - ESP32-C2 TasmotaLED from not present I2S to SPI (#22575) - KNX Scenes index change regression from v14.2.0.4 (#22405) +- Add GUI submenu headers and refresh configuration button text (#22592) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 341f1e172..9b45bfa11 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -157,6 +157,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - ESP32 LVGL library from v9.2.0 to v9.2.2 [#22385](https://github.com/arendst/Tasmota/issues/22385) - ESP32 replaced NeoPixelBus with TasmotaLED [#22556](https://github.com/arendst/Tasmota/issues/22556) - Redesign GUI adding feedback to buttons, shutters and lights +- Add GUI submenu headers and refresh configuration button text (#22592) - Use command `WebButton1` to change GUI shutter 1 name - Unit (k)VAr(h) to (k)var(h) [#22435](https://github.com/arendst/Tasmota/issues/22435) - AHT1X/AHT2X/AHT3X ready for virtual I2C [#22427](https://github.com/arendst/Tasmota/issues/22427) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 0042913a8..c94c35a22 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -280,16 +280,16 @@ #define D_CONSOLE "Konsole" #define D_CONFIRM_RESTART "Bevestig weer te begin" -#define D_CONFIGURE_MODULE "Stel Module in" -#define D_CONFIGURE_WIFI "Stel WiFi in" -#define D_CONFIGURE_MQTT "Stel MQTT in" -#define D_CONFIGURE_DOMOTICZ "Stel Domoticz in" -#define D_CONFIGURE_LOGGING "Stel Logging in" -#define D_CONFIGURE_OTHER "Stel Ander in" +#define D_CONFIGURE_MODULE "Module" +#define D_CONFIGURE_WIFI "WiFi" +#define D_CONFIGURE_MQTT "MQTT" +#define D_CONFIGURE_DOMOTICZ "Domoticz" +#define D_CONFIGURE_LOGGING "Logging" +#define D_CONFIGURE_OTHER "Ander" #define D_CONFIRM_RESET_CONFIGURATION "Bevestig die herstel van die konfigurasie" -#define D_RESET_CONFIGURATION "Stel die konfigurasie terug" -#define D_BACKUP_CONFIGURATION "Rugsteun die konfigurasie" -#define D_RESTORE_CONFIGURATION "Herstel die konfigurasie" +#define D_RESET_CONFIGURATION "Stel terug" +#define D_BACKUP_CONFIGURATION "Rugsteun" +#define D_RESTORE_CONFIGURATION "Herstel" #define D_START_RESTORE "Start restore" #define D_MAIN_MENU "Hoofkieslys" @@ -356,7 +356,7 @@ #define D_SINGLE_DEVICE "enkele toestel" #define D_MULTI_DEVICE "multi toestel" -#define D_CONFIGURE_TEMPLATE "Konfigureer sjabloon" +#define D_CONFIGURE_TEMPLATE "sjabloon" #define D_TEMPLATE_PARAMETERS "Sjabloon parameters" #define D_TEMPLATE_NAME "Naam" #define D_BASE_TYPE "Gebaseer op" @@ -386,10 +386,10 @@ #define D_FLASH_CHIP_SIZE "Flash Size" #define D_FREE_PROGRAM_SPACE "Vrye program grootte" -#define D_UPGRADE_BY_WEBSERVER "Opgradeer per webbediener" +#define D_UPGRADE_BY_WEBSERVER "Per webbediener" #define D_OTA_URL "OTA Url" #define D_START_UPGRADE "Begin opgradering" -#define D_UPGRADE_BY_FILE_UPLOAD "Gradeer op volgens lêeroplaai" +#define D_UPGRADE_BY_FILE_UPLOAD "Volgens lêeroplaai" #define D_UPLOAD_FACTORY "Switching to safeboot partition" #define D_UPLOAD_STARTED "Oplaai begin" #define D_UPGRADE_STARTED "Opgradering is begin" @@ -463,7 +463,7 @@ #define D_DOMOTICZ_UPDATE_TIMER "Dateer tydopdatering op" // xdrv_09_timers.ino -#define D_CONFIGURE_TIMER "Stel Timer in" +#define D_CONFIGURE_TIMER "Timer" #define D_TIMER_PARAMETERS "Timer-parameters" #define D_TIMER_ENABLE "Aktiveer timers" #define D_TIMER_ARM "Aktiveer" @@ -474,7 +474,7 @@ #define D_TIMER_ACTION "Aksie" // xdrv_10_knx.ino -#define D_CONFIGURE_KNX "Stel KNX op" +#define D_CONFIGURE_KNX "KNX" #define D_KNX_PARAMETERS "KNX-parameters" #define D_KNX_GENERAL_CONFIG "Algemene" #define D_KNX_PHYSICAL_ADDRESS "Fisiese adres" @@ -546,7 +546,7 @@ #define D_DOMOTICZ_SHUTTER "Luik" // xdrv_28_pcf8574.ino -#define D_CONFIGURE_PCF8574 "Configure PCF8574" +#define D_CONFIGURE_PCF8574 "PCF8574" #define D_PCF8574_PARAMETERS "PCF8574 parameters" #define D_INVERT_PORTS "Keer poorte om" #define D_DEVICE "Toestel" @@ -571,7 +571,7 @@ #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" // xdrv_79_esp32_ble.ino -#define D_CONFIGURE_BLE "Configure BLE" +#define D_CONFIGURE_BLE "BLE" #define D_BLE_PARAMETERS "Bluetooth Settings" #define D_MQTT_BLE_ENABLE "Enable Bluetooth" #define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" @@ -627,7 +627,7 @@ #define D_HX_CAL_DONE "Gekalibreer" #define D_HX_CAL_FAIL "Kon nie kalibreer nie" #define D_RESET_HX711 "Stel die skaal terug" -#define D_CONFIGURE_HX711 "Stel skaal op" +#define D_CONFIGURE_HX711 "skaal" #define D_HX711_PARAMETERS "Skaal parameters" #define D_ITEM_WEIGHT "Gewig van die item" #define D_REFERENCE_WEIGHT "Verwysingsgewig" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index f379bd8e4..ccf249610 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -280,16 +280,16 @@ #define D_CONSOLE "Console" #define D_CONFIRM_RESTART "Confirm Restart" -#define D_CONFIGURE_MODULE "Configure Module" -#define D_CONFIGURE_WIFI "Configure WiFi" -#define D_CONFIGURE_MQTT "Configure MQTT" -#define D_CONFIGURE_DOMOTICZ "Configure Domoticz" -#define D_CONFIGURE_LOGGING "Configure Logging" -#define D_CONFIGURE_OTHER "Configure Other" +#define D_CONFIGURE_MODULE "Module" +#define D_CONFIGURE_WIFI "WiFi" +#define D_CONFIGURE_MQTT "MQTT" +#define D_CONFIGURE_DOMOTICZ "Domoticz" +#define D_CONFIGURE_LOGGING "Logging" +#define D_CONFIGURE_OTHER "Other" #define D_CONFIRM_RESET_CONFIGURATION "Confirm Reset Configuration" -#define D_RESET_CONFIGURATION "Reset Configuration" -#define D_BACKUP_CONFIGURATION "Backup Configuration" -#define D_RESTORE_CONFIGURATION "Restore Configuration" +#define D_RESET_CONFIGURATION "Reset" +#define D_BACKUP_CONFIGURATION "Backup" +#define D_RESTORE_CONFIGURATION "Restore" #define D_START_RESTORE "Start restore" #define D_MAIN_MENU "Main Menu" @@ -356,7 +356,7 @@ #define D_SINGLE_DEVICE "single device" #define D_MULTI_DEVICE "multi device" -#define D_CONFIGURE_TEMPLATE "Configure Template" +#define D_CONFIGURE_TEMPLATE "Template" #define D_TEMPLATE_PARAMETERS "Template parameters" #define D_TEMPLATE_NAME "Name" #define D_BASE_TYPE "Based on" @@ -386,10 +386,10 @@ #define D_FLASH_CHIP_SIZE "Flash Size" #define D_FREE_PROGRAM_SPACE "Free Program Space" -#define D_UPGRADE_BY_WEBSERVER "Upgrade by web server" +#define D_UPGRADE_BY_WEBSERVER "Use web server" #define D_OTA_URL "OTA Url" #define D_START_UPGRADE "Start upgrade" -#define D_UPGRADE_BY_FILE_UPLOAD "Upgrade by file upload" +#define D_UPGRADE_BY_FILE_UPLOAD "Use file upload" #define D_UPLOAD_FACTORY "Switching to safeboot partition" #define D_UPLOAD_STARTED "Upload started" #define D_UPGRADE_STARTED "Upgrade started" @@ -463,7 +463,7 @@ #define D_DOMOTICZ_UPDATE_TIMER "Update timer" // xdrv_09_timers.ino -#define D_CONFIGURE_TIMER "Configure Timer" +#define D_CONFIGURE_TIMER "Timer" #define D_TIMER_PARAMETERS "Timer parameters" #define D_TIMER_ENABLE "Enable Timers" #define D_TIMER_ARM "Enable" @@ -474,7 +474,7 @@ #define D_TIMER_ACTION "Action" // xdrv_10_knx.ino -#define D_CONFIGURE_KNX "Configure KNX" +#define D_CONFIGURE_KNX "KNX" #define D_KNX_PARAMETERS "KNX Parameters" #define D_KNX_GENERAL_CONFIG "General" #define D_KNX_PHYSICAL_ADDRESS "Physical Address" @@ -528,7 +528,7 @@ // xdrv_89_dali.ino #define D_SENSOR_DALI_RX "Dali RX" #define D_SENSOR_DALI_TX "Dali TX" -#define D_CONFIGURE_DALI "Config DALI" +#define D_CONFIGURE_DALI "DALI" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Today" @@ -546,7 +546,7 @@ #define D_DOMOTICZ_SHUTTER "Shutter" // xdrv_28_pcf8574.ino -#define D_CONFIGURE_PCF8574 "Configure PCF8574" +#define D_CONFIGURE_PCF8574 "PCF8574" #define D_PCF8574_PARAMETERS "PCF8574 parameters" #define D_INVERT_PORTS "Invert Ports" #define D_DEVICE "Device" @@ -571,7 +571,7 @@ #define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" // xdrv_79_esp32_ble.ino -#define D_CONFIGURE_BLE "Configure BLE" +#define D_CONFIGURE_BLE "BLE" #define D_BLE_PARAMETERS "Bluetooth Settings" #define D_MQTT_BLE_ENABLE "Enable Bluetooth" #define D_MQTT_BLE_ACTIVESCAN "Enable Active Scan(*)" @@ -627,7 +627,7 @@ #define D_HX_CAL_DONE "Calibrated" #define D_HX_CAL_FAIL "Calibration failed" #define D_RESET_HX711 "Reset Scale" -#define D_CONFIGURE_HX711 "Configure Scale" +#define D_CONFIGURE_HX711 "Scale" #define D_HX711_PARAMETERS "Scale parameters" #define D_ITEM_WEIGHT "Item weight" #define D_REFERENCE_WEIGHT "Reference weight" diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index ec03b9de1..8c0af448f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -266,6 +266,9 @@ const char HTTP_HEAD_STYLE3[] PROGMEM = "

%s

" // Module name "

%s

"; // Device name +const char HTTP_MENU_HEAD[] PROGMEM = + "


%s

"; + const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM = "
" "
%s" @@ -1952,6 +1955,7 @@ void HandleConfiguration(void) { WSContentStart_P(PSTR(D_CONFIGURATION)); WSContentSendStyle(); + WSContentSend_P(HTTP_MENU_HEAD, D_CONFIGURATION); WSContentButton(BUTTON_MODULE); WSContentButton(BUTTON_WIFI); @@ -2834,6 +2838,7 @@ void HandleInformation(void) { // }1 =
// }2 = WSContentSend_P(HTTP_SCRIPT_INFO_BEGIN); + WSContentSend_P(HTTP_MENU_HEAD, D_INFORMATION); WSContentSend_P(PSTR("
")); WSContentSend_P(PSTR(D_PROGRAM_VERSION "}2%s %s %s"), TasmotaGlobal.version, TasmotaGlobal.image_name, GetCodeCores().c_str()); WSContentSend_P(PSTR("}1" D_BUILD_DATE_AND_TIME "}2%s"), GetBuildDateAndTime().c_str()); @@ -3120,6 +3125,8 @@ void HandleUpgradeFirmware(void) { WSContentStart_P(PSTR(D_FIRMWARE_UPGRADE)); WSContentSendStyle(); + WSContentSend_P(HTTP_MENU_HEAD, D_FIRMWARE_UPGRADE); + WSContentSend_P(HTTP_FORM_UPG, SettingsTextEscaped(SET_OTAURL).c_str()); #ifdef ESP32 if (EspSingleOtaPartition() && !EspRunningFactoryPartition()) { @@ -3657,6 +3664,7 @@ void HandleManagement(void) { WSContentStart_P(PSTR(D_MANAGEMENT)); WSContentSendStyle(); + WSContentSend_P(HTTP_MENU_HEAD, D_MANAGEMENT); WSContentButton(BUTTON_CONSOLE); From 789bbb8b971d1e4c2b30b396e9625554f6072e76 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:40:05 +0100 Subject: [PATCH 193/205] Extent command Knx_Enabled with KNX restart functionality (#22242) --- tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino index 532215e04..5b537620f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino @@ -1422,6 +1422,9 @@ void CmndKnxEnabled(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { Settings->flag.knx_enabled = XdrvMailbox.payload; + if (!Settings->flag.knx_enabled) { + Knx.started = false; + } } ResponseCmndChar (GetStateText(Settings->flag.knx_enabled) ); } From 3a62cc6050e66edaa43ff09d3546f16dfb512a4a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:38:14 +0100 Subject: [PATCH 194/205] Add udp.flush() to KNX receiver (#22242) --- lib/lib_div/esp-knx-ip-0.5.2/src/esp-knx-ip.cpp | 2 ++ tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/lib_div/esp-knx-ip-0.5.2/src/esp-knx-ip.cpp b/lib/lib_div/esp-knx-ip-0.5.2/src/esp-knx-ip.cpp index cc2bbf49a..77abc7428 100644 --- a/lib/lib_div/esp-knx-ip-0.5.2/src/esp-knx-ip.cpp +++ b/lib/lib_div/esp-knx-ip-0.5.2/src/esp-knx-ip.cpp @@ -558,6 +558,8 @@ void ESPKNXIP::__loop_knx() DEBUG_PRINTLN(F("")); + udp.flush(); + knx_ip_pkt_t *knx_pkt = (knx_ip_pkt_t *)buf; DEBUG_PRINT(F("ST: 0x")); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 8c0af448f..c3758c86c 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -267,7 +267,7 @@ const char HTTP_HEAD_STYLE3[] PROGMEM = "

%s

"; // Device name const char HTTP_MENU_HEAD[] PROGMEM = - "


%s

"; + "


%s

"; const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM = "
" From 57fc1797098d9368ec78fb93869fb82a8c5a9338 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:30:04 +0100 Subject: [PATCH 195/205] Platform 2024.12.30 Tasmota Arduino Core 3.1.0.241206 based on IDF 5.3.2 (#22600) * core 3.1.0.241206 * Enterprise support is now conditional in core --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp | 2 ++ platformio_tasmota32.ini | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 44833251a..4fa824a5f 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.8 - - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241117 + - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.0.241206 - [ ] 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/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp b/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp index 601496f9d..6ecf3d7d2 100644 --- a/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp +++ b/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp @@ -34,12 +34,14 @@ ip_addr_t dns_save6[DNS_MAX_SERVERS] = {}; // IPv6 DNS servers #include "tasmota_options.h" #include "lwip/dns.h" +#if CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT wl_status_t WiFiHelper::begin(const char *wpa2_ssid, wpa2_auth_method_t method, const char *wpa2_identity, const char *wpa2_username, const char *wpa2_password, const char *ca_pem, const char *client_crt, const char *client_key, int ttls_phase2_type, int32_t channel, const uint8_t *bssid, bool connect) { WiFiHelper::scrubDNS(); wl_status_t ret = WiFi.begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, ttls_phase2_type, channel, bssid, connect); WiFiHelper::scrubDNS(); return ret; } +#endif // CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT wl_status_t WiFiHelper::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { WiFiHelper::scrubDNS(); diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 3b785d096..0c3b4c955 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -81,7 +81,7 @@ lib_ignore = ${esp32_defaults.lib_ignore} ccronexpr [core32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.11.31/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.12.30/platform-espressif32.zip platform_packages = build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} From 6e6305f5e99415faf82375a17d458b28e54a2290 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:57:13 +0100 Subject: [PATCH 196/205] Rename button Auto-configuration to Auto-Conf --- lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be b/lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be index 13688c46a..cefd8b7b3 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be +++ b/lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be @@ -124,7 +124,7 @@ autoconf_module.init = def (m) # Displays a "Autoconf" button on the configuration page def web_add_config_button() import webserver - webserver.content_send("

") + webserver.content_send("

") end From 0a2fa4ec41625dd124b60f50805434a6554ab1d1 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:57:31 +0100 Subject: [PATCH 197/205] Update Italian language (#22601) --- tasmota/language/it_IT.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 1c614468e..c18525eed 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.4.0.1 - Last update 15.11.2024 + * Updated until v9.4.0.1 - Last update 07.12.2024 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -386,10 +386,10 @@ #define D_FLASH_CHIP_SIZE "Dimensione flash" #define D_FREE_PROGRAM_SPACE "Memoria libera programma" -#define D_UPGRADE_BY_WEBSERVER "Aggiornamento via server web" +#define D_UPGRADE_BY_WEBSERVER "Aggiorna via server web" #define D_OTA_URL "URL OTA" #define D_START_UPGRADE "Esegui aggiornamento" -#define D_UPGRADE_BY_FILE_UPLOAD "Aggiornamento tramite file locale" +#define D_UPGRADE_BY_FILE_UPLOAD "Aggiorna tramite file locale" #define D_UPLOAD_FACTORY "Passaggio a partizione avvio sicuro" #define D_UPLOAD_STARTED "Caricamento..." #define D_UPGRADE_STARTED "Aggiornamento..." @@ -571,7 +571,7 @@ #define D_THERMOSTAT_AUTOTUNE_HYBRID "Regolazione automatica (ibrida)" // xdrv_79_esp32_ble.ino -#define D_CONFIGURE_BLE "Configura BLE" +#define D_CONFIGURE_BLE "BLE" #define D_BLE_PARAMETERS "Impostazioni Bluetooth" #define D_MQTT_BLE_ENABLE "Abilita Bluetooth" #define D_MQTT_BLE_ACTIVESCAN "Abilita scansione attiva (*)" From dd555a06412466421e764eef3097aa426ac451b4 Mon Sep 17 00:00:00 2001 From: arendst Date: Sat, 7 Dec 2024 13:58:23 +0000 Subject: [PATCH 198/205] Solidified Code updated --- .../berry_tasmota/src/solidify/solidified_autoconf_module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_autoconf_module.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_autoconf_module.h index c64fe3823..ef5e1921e 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_autoconf_module.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_autoconf_module.h @@ -121,7 +121,7 @@ static const bvalue be_ktab_class_Autoconf[126] = { /* K113 */ be_nested_str(CFG_X3A_X20loaded_X20_X27_X25s_X27), /* K114 */ be_nested_str(files), /* K115 */ be_nested_str(CFG_X3A_X20exception_X20_X27_X25s_X27_X20_X2D_X20_X27_X25s_X27), - /* K116 */ be_nested_str(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27ac_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3EAuto_X2Dconfiguration_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E), + /* K116 */ be_nested_str(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27ac_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3EAuto_X2DConf_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E), /* K117 */ be_nested_str(add_driver), /* K118 */ be_nested_str(CFG_X3A_X20multiple_X20autoconf_X20files_X20found_X2C_X20aborting_X20_X28_X27_X25s_X27_X20_X2B_X20_X27_X25s_X27_X29), /* K119 */ be_nested_str(CFG_X3A_X20No_X20_X27_X2A_X2Eautoconf_X27_X20file_X20found), From 54d28c9d35738dc61004cba0d66a1882ca0bf943 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:08:57 +0100 Subject: [PATCH 199/205] Update changelogs --- CHANGELOG.md | 2 ++ RELEASENOTES.md | 3 ++- TEMPLATES.md | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81eb1c5ff..1c921bdc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file. - Shelly i4 Gen3 template {"NAME":"Shelly i4 Gen3","GPIO":[0,0,0,4736,32,195,194,193,1,1,192,0,0,0,0,0,0,0,0,0,1,1],"FLAG":0,"BASE":1,"CMND":"AdcGpio3 10000,10000,4000} - Show Active Power Total with any multi-phase energy monitoring (#22579) - Command `SetOption162 1` to disable adding export energy to energy today (#22578) +- ESP32 support for WPA2/3 Enterprise conditional in core v3.1.0.241206 (#22600) ### Breaking Changed - ESP32 ArtNet switches from GRB to RGB encoding (#22556) @@ -26,6 +27,7 @@ All notable changes to this project will be documented in this file. - ESP32 Platform from 2024.11.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.241030 to v3.1.0.241117 and IDF to 5.3.1.241024 (#22504) - Prevent active BLE operations with unencrypted MI-format beacons (#22453) - ESP32 replaced NeoPixelBus with TasmotaLED (#22556) +- ESP32 Platform from 2024.11.31 to 2024.12.30, Framework (Arduino Core) from v3.1.0.241117 to v3.1.0.241206 and IDF to 5.3.2 (#22600) ### Fixed - ESP32 upgrade by file upload response based on file size (#22500) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 9b45bfa11..705df0904 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -140,6 +140,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC [#22370](https://github.com/arendst/Tasmota/issues/22370) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) - Show Active Power Total with any multi-phase energy monitoring [#22579](https://github.com/arendst/Tasmota/issues/22579) +- ESP32 support for WPA2/3 Enterprise conditional in core v3.1.0.241206 [#22600](https://github.com/arendst/Tasmota/issues/22600) - ESP32 ULP lp_core to Berry ULP module (#22567)[#22567](https://github.com/arendst/Tasmota/issues/22567) - ESP32 new BLE filters by name and minimum RSSI [#22530](https://github.com/arendst/Tasmota/issues/22530) - ESP32 Hybrid compile take custom boards settings in account [#22542](https://github.com/arendst/Tasmota/issues/22542) @@ -153,7 +154,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - ESP32 ArtNet switches from GRB to RGB encoding [#22556](https://github.com/arendst/Tasmota/issues/22556) ### Changed -- ESP32 Platform from 2024.09.30 to 2024.11.31, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241117 and IDF to 5.3.1.241024 [#22504](https://github.com/arendst/Tasmota/issues/22504) +- ESP32 Platform from 2024.09.30 to 2024.12.30, Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241206 and IDF to 5.3.2 [#22600](https://github.com/arendst/Tasmota/issues/22600) - ESP32 LVGL library from v9.2.0 to v9.2.2 [#22385](https://github.com/arendst/Tasmota/issues/22385) - ESP32 replaced NeoPixelBus with TasmotaLED [#22556](https://github.com/arendst/Tasmota/issues/22556) - Redesign GUI adding feedback to buttons, shutters and lights diff --git a/TEMPLATES.md b/TEMPLATES.md index e6ce340d4..997e02d80 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -5,7 +5,7 @@ # Templates -Find below the available templates as of October 2024. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) +Find below the available templates as of December 2024. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) ## Adapter Board ``` From aeb965435eb28a8bd9f0f255953901298e249d81 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:01:33 +0100 Subject: [PATCH 200/205] Fix ESP32 energy export calculation --- tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index e8ec16a2b..44d6515e3 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -547,7 +547,7 @@ void EnergyUpdateToday(void) { Energy->kWhtoday[i] += delta; } if (delta < 0) { // Export energy - RtcEnergySettings.energy_export_kWh[i] += ((float)(delta / 100) *-1) / 1000; + RtcEnergySettings.energy_export_kWh[i] += (((float)delta / 100) *-1) / 1000; } } From 523f803b064a1072b236ac6e3d296e9e29dc0580 Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:50:56 +0100 Subject: [PATCH 201/205] Fix DE language (#22603) * Fix DE language * Update de_DE.h --- tasmota/language/de_DE.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 78daae494..f6f5d16af 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v14.1.0.4 - Last update 28.07.2024 + * Updated until v14.3.0.7 - Last update 07.12.2024 \*********************************************************************/ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -285,7 +285,7 @@ #define D_CONFIGURE_MQTT "MQTT" #define D_CONFIGURE_DOMOTICZ "Domoticz" #define D_CONFIGURE_LOGGING "Logging" -#define D_CONFIGURE_OTHER "Weitere" +#define D_CONFIGURE_OTHER "Erweitert" #define D_CONFIRM_RESET_CONFIGURATION "Zurücksetzen bestätigen" #define D_RESET_CONFIGURATION "Zurücksetzen" #define D_BACKUP_CONFIGURATION "Sichern" @@ -341,7 +341,7 @@ #define D_SYSLOG_PORT "Syslog Port" #define D_TELEMETRY_PERIOD "Telemetrieperiode" -#define D_OTHER_PARAMETERS "Weitere" +#define D_OTHER_PARAMETERS "Einstellungen" #define D_TEMPLATE "Vorlage" #define D_ACTIVATE "Aktivieren" #define D_DEVICE_NAME "Gerätename" @@ -356,7 +356,7 @@ #define D_SINGLE_DEVICE "Einzelnes Gerät" #define D_MULTI_DEVICE "Mehrfachgerät" -#define D_CONFIGURE_TEMPLATE "konfigurieren" +#define D_CONFIGURE_TEMPLATE "Vorlage" #define D_TEMPLATE_PARAMETERS "Parameter" #define D_TEMPLATE_NAME "Name" #define D_BASE_TYPE "basiert auf" @@ -388,7 +388,7 @@ #define D_UPGRADE_BY_WEBSERVER "Update über Webserver" #define D_OTA_URL "OTA-URL" -#define D_START_UPGRADE "starten" +#define D_START_UPGRADE "Starten" #define D_UPGRADE_BY_FILE_UPLOAD "Update Datei hochladen" #define D_UPLOAD_FACTORY "Wechsle zur Safeboot Partition" #define D_UPLOAD_STARTED "Upload gestartet" From ed520140a1935fd1699c3b3234bd9c1a12797494 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 7 Dec 2024 22:44:45 +0100 Subject: [PATCH 202/205] Add support for Sonoff POWCT Energy Export Active (#22596) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + .../tasmota_xnrg_energy/xnrg_19_cse7761.ino | 59 +++++++++++++------ 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c921bdc2..27277195b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file. - Show Active Power Total with any multi-phase energy monitoring (#22579) - Command `SetOption162 1` to disable adding export energy to energy today (#22578) - ESP32 support for WPA2/3 Enterprise conditional in core v3.1.0.241206 (#22600) +- Support for Sonoff POWCT Energy Export Active (#22596) ### Breaking Changed - ESP32 ArtNet switches from GRB to RGB encoding (#22556) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 705df0904..68f4116ac 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -133,6 +133,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Support for US AQI and EPA AQI in PMS5003x sensors [#22294](https://github.com/arendst/Tasmota/issues/22294) - Support for MS5837 pressure and temperature sensor [#22376](https://github.com/arendst/Tasmota/issues/22376) - Support for TM1640 based IoTTimer by Stefan Oskamp [#21376](https://github.com/arendst/Tasmota/issues/21376) +- Support for Sonoff POWCT Energy Export Active [#22596](https://github.com/arendst/Tasmota/issues/22596) - HLK-LD2410 Engineering mode [#21880](https://github.com/arendst/Tasmota/issues/21880) - Mitsubishi Electric HVAC Operation time for MiElHVAC [#22334](https://github.com/arendst/Tasmota/issues/22334) - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino index 1a4bd3002..960102513 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino @@ -33,6 +33,21 @@ * Based on datasheet from ChipSea and analysing serial data * See https://github.com/arendst/Tasmota/discussions/10793 * https://goldenrelay.en.alibaba.com/product/62119012875-811845870/GOLDEN_GI_1A_5LH_SPST_5V_5A_10A_250VAC_NO_18_5_10_5_15_3mm_sealed_type_all_certificate_compliances_class_F_SPDT_Form_available.html + * + * Model differences: + * Function Model1 Model2 Remark + * ------------------------------ ------- ------- ------------------------------------------------- + * Sonoff DualR3 PowCT + * Processor ESP32 ESP32 + * CSE7761 Rx 1 2 Index defines model number + * Number of inputs 2 1 Count of CSE7761 inputs used + * Current measurement device shunt CT CT = Current Transformer + * Common voltage Yes Yes Show common voltage in GUI/JSON + * Common frequency Yes Yes Show common frequency in GUI/JSON + * Swapped inputs Yes No Current direction defined by hardware design - Fixed by Tasmota + * Support Zero Cross detection Yes No Tasmota supports zero cross detection only on DualR3 due to timing + * Support Export Active No Yes Only CT supports correct negative value detection + * Show negative power No Yes Only CT supports correct negative value detection \*********************************************************************************************/ #define XNRG_19 19 @@ -96,8 +111,9 @@ struct { uint32_t frequency = 0; uint32_t voltage_rms = 0; uint32_t current_rms[2] = { 0 }; - uint32_t energy[2] = { 0 }; + int32_t energy[2] = { 0 }; uint32_t active_power[2] = { 0 }; + uint32_t power_factor[2] = { 0 }; uint16_t coefficient[8] = { 0 }; uint8_t energy_update[2] = { 0 }; uint8_t init = 4; @@ -445,32 +461,27 @@ void Cse7761GetData(void) { CSE7761Data.frequency = (value >= 0x8000) ? 0 : value; #endif // CSE7761_FREQUENCY - value = Cse7761ReadFallback(CSE7761_REG_RMSIA, CSE7761Data.current_rms[0], 3); -#ifdef CSE7761_SIMULATE - value = 455; -#endif - CSE7761Data.current_rms[0] = ((value >= 0x800000) || (value < 1600)) ? 0 : value; // No load threshold of 10mA - value = Cse7761ReadFallback(CSE7761_REG_POWERPA, CSE7761Data.active_power[0], 4); -#ifdef CSE7761_SIMULATE - value = 217; -#endif - CSE7761Data.active_power[0] = (0 == CSE7761Data.current_rms[0]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value; + for (uint32_t channel = 0; channel < Energy->phase_count; channel++) { + if (CSE7761_MODEL_POWCT == CSE7761Data.model) { + Cse7761Write(CSE7761_SPECIAL_COMMAND, (channel) ? CSE7761_CMD_CHAN_B_SELECT : CSE7761_CMD_CHAN_A_SELECT); + CSE7761Data.power_factor[channel] = Cse7761ReadFallback(CSE7761_REG_POWERFACTOR, CSE7761Data.power_factor[channel], 3); + } - if (2 == Energy->phase_count) { - value = Cse7761ReadFallback(CSE7761_REG_RMSIB, CSE7761Data.current_rms[1], 3); + value = Cse7761ReadFallback((channel) ? CSE7761_REG_RMSIB : CSE7761_REG_RMSIA, CSE7761Data.current_rms[channel], 3); #ifdef CSE7761_SIMULATE - value = 29760; // 0.185A + value = 455; #endif - CSE7761Data.current_rms[1] = ((value >= 0x800000) || (value < 1600)) ? 0 : value; // No load threshold of 10mA - value = Cse7761ReadFallback(CSE7761_REG_POWERPB, CSE7761Data.active_power[1], 4); + CSE7761Data.current_rms[channel] = ((value >= 0x800000) || (value < 1600)) ? 0 : value; // No load threshold of 10mA + value = Cse7761ReadFallback((channel) ? CSE7761_REG_POWERPB : CSE7761_REG_POWERPA, CSE7761Data.active_power[channel], 4); #ifdef CSE7761_SIMULATE - value = 2126641; // 44.05W + value = 217; #endif - CSE7761Data.active_power[1] = (0 == CSE7761Data.current_rms[1]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value; + CSE7761Data.active_power[channel] = (0 == CSE7761Data.current_rms[channel]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value; } - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("C61: F%d, U%d, I%d/%d, P%d/%d"), + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("C61: F%d, U%d, PF%d/%d, I%d/%d, P%d/%d"), CSE7761Data.frequency, CSE7761Data.voltage_rms, + CSE7761Data.power_factor[0], CSE7761Data.power_factor[1], CSE7761Data.current_rms[0], CSE7761Data.current_rms[1], CSE7761Data.active_power[0], CSE7761Data.active_power[1]); @@ -497,6 +508,13 @@ void Cse7761GetData(void) { if (0 == Energy->active_power[channel]) { Energy->current[channel] = 0; } else { + if (CSE7761_MODEL_POWCT == CSE7761Data.model) { + int32_t power_factor = CSE7761Data.power_factor[channel] << 8; + if (power_factor < 0) { + // power factor is negative and active power is not zero -> handle negative active power + Energy->active_power[channel] = -Energy->active_power[channel]; + } + } uint32_t current_calibration = EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION, channel); // Current = RmsIA * RmsIAC / 0x800000 // Energy->current[channel] = (float)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A @@ -628,6 +646,9 @@ void Cse7761DrvInit(void) { if (CSE7761_MODEL_DUALR3 == CSE7761Data.model) { Energy->phase_count = 2; // Handle two channels as two phases } + if (CSE7761_MODEL_POWCT == CSE7761Data.model) { + Energy->local_energy_active_export = true; // Support energy export + } Energy->voltage_common = true; // Use common voltage #ifdef CSE7761_FREQUENCY Energy->frequency_common = true; // Use common frequency From 364fa21fc4f974610d45e9775929d4e586ca9a87 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Sun, 8 Dec 2024 10:29:45 +0100 Subject: [PATCH 203/205] Haspmota fix chart color series --- lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be index 082110dcb..9d65d6fb6 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be +++ b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be @@ -2187,10 +2187,10 @@ class lvh_chart : lvh_obj end def set_series1_color(color) - self._lv_obj.set_series_color(self._ser1, color) + self._lv_obj.set_series_color(self._ser1, self.parse_color(color)) end def set_series2_color(color) - self._lv_obj.set_series_color(self._ser2, color) + self._lv_obj.set_series_color(self._ser2, self.parse_color(color)) end def set_h_div_line_count(_h_div) self._h_div = _h_div From 2969ee91a46a91e3259c111e2ebb9c68890d28a3 Mon Sep 17 00:00:00 2001 From: s-hadinger Date: Sun, 8 Dec 2024 09:30:29 +0000 Subject: [PATCH 204/205] Solidified Code updated --- .../src/solidify/solidified_lv_haspmota.h | 97 ++++++++++--------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h index 3936938da..be6f8f134 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h +++ b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h @@ -9182,8 +9182,8 @@ be_local_class(lvh_span, })), be_str_weak(lvh_span) ); -// compact class 'lvh_chart' ktab size: 24, total: 54 (saved 240 bytes) -static const bvalue be_ktab_class_lvh_chart[24] = { +// compact class 'lvh_chart' ktab size: 25, total: 56 (saved 248 bytes) +static const bvalue be_ktab_class_lvh_chart[25] = { /* K0 */ be_nested_str_weak(_y_min), /* K1 */ be_nested_str_weak(_lv_obj), /* K2 */ be_nested_str_weak(set_next_value), @@ -9195,19 +9195,20 @@ static const bvalue be_ktab_class_lvh_chart[24] = { /* K8 */ be_nested_str_weak(_y_max), /* K9 */ be_nested_str_weak(_ser2), /* K10 */ be_nested_str_weak(set_series_color), - /* K11 */ be_const_int(0), - /* K12 */ be_nested_str_weak(_h_div), - /* K13 */ be_const_int(3), - /* K14 */ be_nested_str_weak(_v_div), - /* K15 */ be_nested_str_weak(set_update_mode), - /* K16 */ be_nested_str_weak(CHART_UPDATE_MODE_SHIFT), - /* K17 */ be_nested_str_weak(add_series), - /* K18 */ be_nested_str_weak(color), - /* K19 */ be_const_int(15615044), - /* K20 */ be_const_int(4517444), - /* K21 */ be_nested_str_weak(_val), - /* K22 */ be_nested_str_weak(add_point), - /* K23 */ be_nested_str_weak(set_div_line_count), + /* K11 */ be_nested_str_weak(parse_color), + /* K12 */ be_const_int(0), + /* K13 */ be_nested_str_weak(_h_div), + /* K14 */ be_const_int(3), + /* K15 */ be_nested_str_weak(_v_div), + /* K16 */ be_nested_str_weak(set_update_mode), + /* K17 */ be_nested_str_weak(CHART_UPDATE_MODE_SHIFT), + /* K18 */ be_nested_str_weak(add_series), + /* K19 */ be_nested_str_weak(color), + /* K20 */ be_const_int(15615044), + /* K21 */ be_const_int(4517444), + /* K22 */ be_nested_str_weak(_val), + /* K23 */ be_nested_str_weak(add_point), + /* K24 */ be_nested_str_weak(set_div_line_count), }; @@ -9360,7 +9361,7 @@ be_local_closure(class_lvh_chart_add_point2, /* name */ ********************************************************************/ be_local_closure(class_lvh_chart_set_series1_color, /* name */ be_nested_proto( - 6, /* nstack */ + 8, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -9371,13 +9372,15 @@ be_local_closure(class_lvh_chart_set_series1_color, /* name */ &be_ktab_class_lvh_chart, /* shared constants */ be_str_weak(set_series1_color), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ + ( &(const binstruction[ 8]) { /* code */ 0x88080101, // 0000 GETMBR R2 R0 K1 0x8C08050A, // 0001 GETMET R2 R2 K10 0x88100103, // 0002 GETMBR R4 R0 K3 - 0x5C140200, // 0003 MOVE R5 R1 - 0x7C080600, // 0004 CALL R2 3 - 0x80000000, // 0005 RET 0 + 0x8C14010B, // 0003 GETMET R5 R0 K11 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x7C140400, // 0005 CALL R5 2 + 0x7C080600, // 0006 CALL R2 3 + 0x80000000, // 0007 RET 0 }) ) ); @@ -9389,7 +9392,7 @@ be_local_closure(class_lvh_chart_set_series1_color, /* name */ ********************************************************************/ be_local_closure(class_lvh_chart_set_series2_color, /* name */ be_nested_proto( - 6, /* nstack */ + 8, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -9400,13 +9403,15 @@ be_local_closure(class_lvh_chart_set_series2_color, /* name */ &be_ktab_class_lvh_chart, /* shared constants */ be_str_weak(set_series2_color), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ + ( &(const binstruction[ 8]) { /* code */ 0x88080101, // 0000 GETMBR R2 R0 K1 0x8C08050A, // 0001 GETMET R2 R2 K10 0x88100109, // 0002 GETMBR R4 R0 K9 - 0x5C140200, // 0003 MOVE R5 R1 - 0x7C080600, // 0004 CALL R2 3 - 0x80000000, // 0005 RET 0 + 0x8C14010B, // 0003 GETMET R5 R0 K11 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x7C140400, // 0005 CALL R5 2 + 0x7C080600, // 0006 CALL R2 3 + 0x80000000, // 0007 RET 0 }) ) ); @@ -9462,32 +9467,32 @@ be_local_closure(class_lvh_chart_post_init, /* name */ be_str_weak(post_init), &be_const_str_solidified, ( &(const binstruction[32]) { /* code */ - 0x9002010B, // 0000 SETMBR R0 K0 K11 + 0x9002010C, // 0000 SETMBR R0 K0 K12 0x54060063, // 0001 LDINT R1 100 0x90021001, // 0002 SETMBR R0 K8 R1 - 0x9002190D, // 0003 SETMBR R0 K12 K13 + 0x90021B0E, // 0003 SETMBR R0 K13 K14 0x54060004, // 0004 LDINT R1 5 - 0x90021C01, // 0005 SETMBR R0 K14 R1 + 0x90021E01, // 0005 SETMBR R0 K15 R1 0x88040101, // 0006 GETMBR R1 R0 K1 - 0x8C04030F, // 0007 GETMET R1 R1 K15 + 0x8C040310, // 0007 GETMET R1 R1 K16 0xB80E0C00, // 0008 GETNGBL R3 K6 - 0x880C0710, // 0009 GETMBR R3 R3 K16 + 0x880C0711, // 0009 GETMBR R3 R3 K17 0x7C040400, // 000A CALL R1 2 0x88040101, // 000B GETMBR R1 R0 K1 - 0x8C040311, // 000C GETMET R1 R1 K17 + 0x8C040312, // 000C GETMET R1 R1 K18 0xB80E0C00, // 000D GETNGBL R3 K6 - 0x8C0C0712, // 000E GETMET R3 R3 K18 - 0x58140013, // 000F LDCONST R5 K19 + 0x8C0C0713, // 000E GETMET R3 R3 K19 + 0x58140014, // 000F LDCONST R5 K20 0x7C0C0400, // 0010 CALL R3 2 0xB8120C00, // 0011 GETNGBL R4 K6 0x88100907, // 0012 GETMBR R4 R4 K7 0x7C040600, // 0013 CALL R1 3 0x90020601, // 0014 SETMBR R0 K3 R1 0x88040101, // 0015 GETMBR R1 R0 K1 - 0x8C040311, // 0016 GETMET R1 R1 K17 + 0x8C040312, // 0016 GETMET R1 R1 K18 0xB80E0C00, // 0017 GETNGBL R3 K6 - 0x8C0C0712, // 0018 GETMET R3 R3 K18 - 0x58140014, // 0019 LDCONST R5 K20 + 0x8C0C0713, // 0018 GETMET R3 R3 K19 + 0x58140015, // 0019 LDCONST R5 K21 0x7C0C0400, // 001A CALL R3 2 0xB8120C00, // 001B GETNGBL R4 K6 0x88100907, // 001C GETMBR R4 R4 K7 @@ -9542,8 +9547,8 @@ be_local_closure(class_lvh_chart_set_val, /* name */ be_str_weak(set_val), &be_const_str_solidified, ( &(const binstruction[ 5]) { /* code */ - 0x90022A01, // 0000 SETMBR R0 K21 R1 - 0x8C080116, // 0001 GETMET R2 R0 K22 + 0x90022C01, // 0000 SETMBR R0 K22 R1 + 0x8C080117, // 0001 GETMET R2 R0 K23 0x5C100200, // 0002 MOVE R4 R1 0x7C080400, // 0003 CALL R2 2 0x80000000, // 0004 RET 0 @@ -9570,11 +9575,11 @@ be_local_closure(class_lvh_chart_set_v_div_line_count, /* name */ be_str_weak(set_v_div_line_count), &be_const_str_solidified, ( &(const binstruction[ 7]) { /* code */ - 0x90021C01, // 0000 SETMBR R0 K14 R1 + 0x90021E01, // 0000 SETMBR R0 K15 R1 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x8C080517, // 0002 GETMET R2 R2 K23 - 0x8810010C, // 0003 GETMBR R4 R0 K12 - 0x8814010E, // 0004 GETMBR R5 R0 K14 + 0x8C080518, // 0002 GETMET R2 R2 K24 + 0x8810010D, // 0003 GETMBR R4 R0 K13 + 0x8814010F, // 0004 GETMBR R5 R0 K15 0x7C080600, // 0005 CALL R2 3 0x80000000, // 0006 RET 0 }) @@ -9600,11 +9605,11 @@ be_local_closure(class_lvh_chart_set_h_div_line_count, /* name */ be_str_weak(set_h_div_line_count), &be_const_str_solidified, ( &(const binstruction[ 7]) { /* code */ - 0x90021801, // 0000 SETMBR R0 K12 R1 + 0x90021A01, // 0000 SETMBR R0 K13 R1 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x8C080517, // 0002 GETMET R2 R2 K23 - 0x8810010C, // 0003 GETMBR R4 R0 K12 - 0x8814010E, // 0004 GETMBR R5 R0 K14 + 0x8C080518, // 0002 GETMET R2 R2 K24 + 0x8810010D, // 0003 GETMBR R4 R0 K13 + 0x8814010F, // 0004 GETMBR R5 R0 K15 0x7C080600, // 0005 CALL R2 3 0x80000000, // 0006 RET 0 }) From d6c1617fc554d879aa9885581366256e5b2996ab Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 8 Dec 2024 14:43:48 +0100 Subject: [PATCH 205/205] Skip code not needed on single phase --- tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino index 960102513..403824eba 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino @@ -44,7 +44,7 @@ * Current measurement device shunt CT CT = Current Transformer * Common voltage Yes Yes Show common voltage in GUI/JSON * Common frequency Yes Yes Show common frequency in GUI/JSON - * Swapped inputs Yes No Current direction defined by hardware design - Fixed by Tasmota + * Inverted inputs Yes No Current direction defined by hardware design - Fixed by Tasmota * Support Zero Cross detection Yes No Tasmota supports zero cross detection only on DualR3 due to timing * Support Export Active No Yes Only CT supports correct negative value detection * Show negative power No Yes Only CT supports correct negative value detection @@ -463,7 +463,9 @@ void Cse7761GetData(void) { for (uint32_t channel = 0; channel < Energy->phase_count; channel++) { if (CSE7761_MODEL_POWCT == CSE7761Data.model) { - Cse7761Write(CSE7761_SPECIAL_COMMAND, (channel) ? CSE7761_CMD_CHAN_B_SELECT : CSE7761_CMD_CHAN_A_SELECT); + if (Energy->phase_count > 1) { + Cse7761Write(CSE7761_SPECIAL_COMMAND, (channel) ? CSE7761_CMD_CHAN_B_SELECT : CSE7761_CMD_CHAN_A_SELECT); + } CSE7761Data.power_factor[channel] = Cse7761ReadFallback(CSE7761_REG_POWERFACTOR, CSE7761Data.power_factor[channel], 3); }