Merge branch 'arendst:development' into development

This commit is contained in:
philrich 2022-05-04 00:31:31 +02:00 committed by GitHub
commit f72dce2f06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
82 changed files with 5769 additions and 1980 deletions

View File

@ -39,6 +39,10 @@ jobs:
- tasmota32-lvgl
- tasmota32c3
- tasmota32solo1
- tasmota32-safemode
- tasmota32c3-safemode
- tasmota32s2-safemode
- tasmota32s3-safemode
steps:
- uses: actions/checkout@v2
with:
@ -117,7 +121,9 @@ jobs:
[ ! -f ./mv_firmware/firmware/tasmota32-core2.* ] || mv ./mv_firmware/firmware/tasmota32-core2.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-bluetooth.* ] || mv ./mv_firmware/firmware/tasmota32-bluetooth.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32c3*.* ] || mv ./mv_firmware/firmware/tasmota32c3*.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./firmware/tasmota32/languages/
[ ! -f ./mv_firmware/firmware/tasmota32-safemode* ] || mv ./mv_firmware/firmware/tasmota32-safemode* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-* ] || mv ./mv_firmware/firmware/tasmota32-* ./firmware/tasmota32/languages/
[ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/* ] || mv ./mv_firmware/firmware/* ./firmware/tasmota/languages/
- name: Display files to transfer
run: ls -R ./*

View File

@ -43,6 +43,10 @@ jobs:
- tasmota32s2
- tasmota32c3
- tasmota32solo1
- tasmota32-safemode
- tasmota32c3-safemode
- tasmota32s2-safemode
- tasmota32s3-safemode
steps:
- uses: actions/checkout@v2
- name: Set up Python

View File

@ -12,6 +12,7 @@ jobs:
copy_change:
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
steps:
- uses: actions/checkout@v2
- name: Push I2CDevices.md to https://github.com/Tasmota/docs

View File

@ -216,6 +216,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_HRE | - | - / x | - | x | - | - |
| USE_A4988_STEPPER | - | - / - | - | - | - | - |
| USE_NEOPOOL | - | - / - | - | - | - | - |
| USE_FLOWRATEMETER | - | - / - | - | - | - | - |
| | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_DISPLAY | - | - / - | - | - | - | x |

View File

@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Command ``EnergyExportActive<phase>`` to (p)reset energy export active for supported devices. Currently ADE7880 only (#13515)
- Sonoff SPM delayed SetPowerOnState (#13447)
- Command ``SetOption139 0/1`` to switch between pressure unit "mmHg" (0) or "inHg" (1) when ``SO24 1`` (#15350)
- Support for flowrate meters like YF-DN50 and similary
### Changed

View File

@ -1,7 +1,7 @@
![Tasmota logo](/tools/logo/TASMOTA_FullLogo_Vector.svg)
Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) and [ESP32](https://en.wikipedia.org/wiki/ESP32) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**.
_Written for PlatformIO with limited support for Arduino IDE._
_Written for PlatformIO._
[![GitHub version](https://img.shields.io/github/release/arendst/Tasmota.svg)](http://ota.tasmota.com/tasmota/release)
[![GitHub download](https://img.shields.io/github/downloads/arendst/Tasmota/total.svg)](https://github.com/arendst/Tasmota/releases/latest)

View File

@ -30,8 +30,8 @@
"arduino": {
"flash_extra_images": [
[
"0x2E0000",
"variants/tasmota/tasmota32-minicustom.bin"
"0x10000",
"variants/tasmota/tasmota32-safemode.bin"
]
]
},

43
boards/esp32c3_2APP.json Normal file
View File

@ -0,0 +1,43 @@
{
"build": {
"arduino":{
"ldscript": "esp32c3_out.ld"
},
"core": "esp32",
"extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3",
"f_cpu": "160000000L",
"f_flash": "80000000L",
"flash_mode": "dout",
"mcu": "esp32c3",
"variant": "esp32c3",
"partitions": "esp32_partition_app2880k_spiffs320k.csv"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32c3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32c3-safemode.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html",
"vendor": "Espressif"
}

43
boards/esp32s2_2APP.json Normal file
View File

@ -0,0 +1,43 @@
{
"build": {
"arduino":{
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S2",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dout",
"mcu": "esp32s2",
"variant": "esp32s2",
"partitions": "esp32_partition_app2880k_spiffs320k.csv"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s2.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32s2-safemode.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html",
"vendor": "Espressif"
}

46
boards/esp32s3_2APP.json Normal file
View File

@ -0,0 +1,46 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
"memory_type": "qspi_qspi"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "esp32_partition_app2880k_spiffs320k.csv"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32s3-safemode.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
"vendor": "Espressif"
}

View File

@ -1,6 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x2D0000,
factory, app, factory, 0x2E0000,0xD0000,
factory, app, factory, 0x10000, 0xD0000,
app0, app, ota_0, 0xE0000, 0x2D0000,
spiffs, data, spiffs, 0x3B0000,0x50000,

1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 factory app ota_0 factory 0x10000 0x2D0000 0xD0000
5 factory app0 app factory ota_0 0x2E0000 0xE0000 0xD0000 0x2D0000
6 spiffs data spiffs 0x3B0000 0x50000

View File

@ -46,6 +46,8 @@ be_extern_native_module(hue_ntv);
be_extern_native_module(hue_bridge);
be_extern_native_module(uuid);
be_extern_native_module(animate);
be_extern_native_module(partition_core);
be_extern_native_module(crc);
#ifdef USE_LVGL
be_extern_native_module(lv);
be_extern_native_module(lv_extra);
@ -146,6 +148,8 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
&be_native_module(webserver),
#endif // USE_WEBSERVER
&be_native_module(flash),
&be_native_module(partition_core),
&be_native_module(crc),
/* user-defined modules register end */
NULL /* do not remove */

View File

@ -1,4 +1,6 @@
extern const bcstring be_const_str_;
extern const bcstring be_const_str_00;
extern const bcstring be_const_str_AA50;
extern const bcstring be_const_str_AES_GCM;
extern const bcstring be_const_str_ALIGN_BOTTOM_MID;
extern const bcstring be_const_str_ALIGN_LEFT_MID;
@ -16,12 +18,13 @@ extern const bcstring be_const_str_Auto_X2Dconfiguration;
extern const bcstring be_const_str_BECDFE;
extern const bcstring be_const_str_BLE;
extern const bcstring be_const_str_BRY_X3A_X20ERROR_X2C_X20bad_X20json_X3A_X20;
extern const bcstring be_const_str_BRY_X3A_X20Exception_X3E_X20_X27;
extern const bcstring be_const_str_BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s;
extern const bcstring be_const_str_BRY_X3A_X20argument_X20must_X20be_X20a_X20function;
extern const bcstring be_const_str_BRY_X3A_X20bytecode_X20has_X20wrong_X20version_X20_X27_X25s_X27_X20_X28_X25i_X29;
extern const bcstring be_const_str_BRY_X3A_X20corrupt_X20bytecode_X20_X27_X25s_X27;
extern const bcstring be_const_str_BRY_X3A_X20could_X20not_X20save_X20compiled_X20file_X20_X25s_X20_X28_X25s_X29;
extern const bcstring be_const_str_BRY_X3A_X20failed_X20to_X20load_X20_X27_X25s_X27_X20_X28_X25s_X29;
extern const bcstring be_const_str_BRY_X3A_X20failed_X20to_X20load_X20_X27_X25s_X27_X20_X28_X25s_X20_X2D_X20_X25s_X29;
extern const bcstring be_const_str_BRY_X3A_X20failed_X20to_X20load_X20_persist_X2Ejson;
extern const bcstring be_const_str_BRY_X3A_X20failed_X20to_X20load_X20compiled_X20_X27_X25s_X27_X20_X28_X25s_X29;
extern const bcstring be_const_str_BRY_X3A_X20failed_X20to_X20run_X20compiled_X20code_X20_X27_X25s_X27_X20_X2D_X20_X25s;
@ -50,12 +53,14 @@ extern const bcstring be_const_str_COLOR_BLACK;
extern const bcstring be_const_str_COLOR_WHITE;
extern const bcstring be_const_str_CT;
extern const bcstring be_const_str_DIMMER;
extern const bcstring be_const_str_EBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
extern const bcstring be_const_str_EC_C25519;
extern const bcstring be_const_str_EVENT_DELETE;
extern const bcstring be_const_str_EVENT_DRAW_MAIN;
extern const bcstring be_const_str_EVENT_DRAW_PART_BEGIN;
extern const bcstring be_const_str_EVENT_DRAW_PART_END;
extern const bcstring be_const_str_EXTERNAL_I2S;
extern const bcstring be_const_str_FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
extern const bcstring be_const_str_False;
extern const bcstring be_const_str_GET;
extern const bcstring be_const_str_HTTP_GET;
@ -64,17 +69,22 @@ extern const bcstring be_const_str_I2C_Driver;
extern const bcstring be_const_str_I2C_X3A;
extern const bcstring be_const_str_INTERNAL_DAC;
extern const bcstring be_const_str_INTERNAL_PDM;
extern const bcstring be_const_str_Invalid_X20ota_X20partition_X20number;
extern const bcstring be_const_str_LVG_X3A_X20call_X20to_X20unsupported_X20callback;
extern const bcstring be_const_str_Leds;
extern const bcstring be_const_str_MAX_RMT;
extern const bcstring be_const_str_MD5;
extern const bcstring be_const_str_MI32;
extern const bcstring be_const_str_No_X20SPIFFS_X20partition_X20found;
extern const bcstring be_const_str_None;
extern const bcstring be_const_str_OPTION_A;
extern const bcstring be_const_str_OneWire;
extern const bcstring be_const_str_PART_MAIN;
extern const bcstring be_const_str_POST;
extern const bcstring be_const_str_Parameter_X20error;
extern const bcstring be_const_str_Partition;
extern const bcstring be_const_str_Partition_info;
extern const bcstring be_const_str_Partition_otadata;
extern const bcstring be_const_str_RELAY;
extern const bcstring be_const_str_RES_OK;
extern const bcstring be_const_str_RGB;
@ -111,6 +121,7 @@ extern const bcstring be_const_str_TAP_X3A_X20Loaded_X20Tasmota_X20App_X20_X27_X
extern const bcstring be_const_str_TASMOTA;
extern const bcstring be_const_str_Tasmota;
extern const bcstring be_const_str_Tele;
extern const bcstring be_const_str_Too_X20many_X20partiition_X20slots;
extern const bcstring be_const_str_Trigger;
extern const bcstring be_const_str_True;
extern const bcstring be_const_str_Unknown;
@ -120,7 +131,10 @@ extern const bcstring be_const_str_WS2812_GRB;
extern const bcstring be_const_str_Wire;
extern const bcstring be_const_str__;
extern const bcstring be_const_str__X0A;
extern const bcstring be_const_str__X0A_X29_X3E;
extern const bcstring be_const_str__X20;
extern const bcstring be_const_str__X20_X20;
extern const bcstring be_const_str__X20_X28;
extern const bcstring be_const_str__X21_X3D;
extern const bcstring be_const_str__X21_X3D_X3D;
extern const bcstring be_const_str__X22;
@ -138,7 +152,9 @@ extern const bcstring be_const_str__X2508x_X2D_X2504x_X2D_X2504x_X2D_X2504x_X2D_
extern const bcstring be_const_str__X25s_X2Eautoconf;
extern const bcstring be_const_str__X26lt_X3BError_X3A_X20apply_X20new_X20or_X20remove_X26gt_X3B;
extern const bcstring be_const_str__X26lt_X3BNone_X26gt_X3B;
extern const bcstring be_const_str__X27_X20_X2D_X20;
extern const bcstring be_const_str__X28_X29;
extern const bcstring be_const_str__X29;
extern const bcstring be_const_str__X2A;
extern const bcstring be_const_str__X2B;
extern const bcstring be_const_str__X2C;
@ -172,6 +188,9 @@ extern const bcstring be_const_str__X3C_X3D;
extern const bcstring be_const_str__X3Cbutton_X20name_X3D_X27reapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3ERe_X2Dapply_X20current_X20configuration_X3C_X2Fbutton_X3E;
extern const bcstring be_const_str__X3Cbutton_X20name_X3D_X27zipapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3EApply_X20configuration_X3C_X2Fbutton_X3E;
extern const bcstring be_const_str__X3Cfieldset_X3E_X3Cstyle_X3E_X2Ebdis_X7Bbackground_X3A_X23888_X3B_X7D_X2Ebdis_X3Ahover_X7Bbackground_X3A_X23888_X3B_X7D_X3C_X2Fstyle_X3E;
extern const bcstring be_const_str__X3Cinstance_X3A_X20Partition_X28_X5B_X0A;
extern const bcstring be_const_str__X3Cinstance_X3A_X20Partition_info_X28_X25d_X25s_X2C_X25d_X25s_X2C0x_X2508X_X2C0x_X2508X_X2C_X27_X25s_X27_X2C0x_X25X_X29_X3E;
extern const bcstring be_const_str__X3Cinstance_X3A_X20Partition_otadata_X28ota_active_X3A_X25d_X2C_X20ota_seq_X3D_X5B_X25d_X2C_X25d_X5D_X2C_X20ota_max_X3D_X25d_X29_X3E;
extern const bcstring be_const_str__X3Cinstance_X3A_X20_X25s_X28_X25s_X2C_X20_X25s_X2C_X20_X25s_X29;
extern const bcstring be_const_str__X3Clabel_X3EChoose_X20a_X20device_X20configuration_X3A_X3C_X2Flabel_X3E_X3Cbr_X3E;
extern const bcstring be_const_str__X3Clambda_X3E;
@ -195,6 +214,7 @@ extern const bcstring be_const_str__X3E_X3D;
extern const bcstring be_const_str__X3F;
extern const bcstring be_const_str__X5B;
extern const bcstring be_const_str__X5D;
extern const bcstring be_const_str__X5D_X2C_X0A_X20_X20;
extern const bcstring be_const_str__X7B;
extern const bcstring be_const_str__X7B_X7D;
extern const bcstring be_const_str__X7Bs_X7DBatt_X20Current_X7Bm_X7D_X25_X2E1f_X20mA_X7Be_X7D;
@ -238,12 +258,15 @@ extern const bcstring be_const_str__rules;
extern const bcstring be_const_str__settings_def;
extern const bcstring be_const_str__settings_ptr;
extern const bcstring be_const_str__splash;
extern const bcstring be_const_str__subscribe;
extern const bcstring be_const_str__t;
extern const bcstring be_const_str__timers;
extern const bcstring be_const_str__validate;
extern const bcstring be_const_str__write;
extern const bcstring be_const_str_a;
extern const bcstring be_const_str_abs;
extern const bcstring be_const_str_acos;
extern const bcstring be_const_str_active_otadata;
extern const bcstring be_const_str_add;
extern const bcstring be_const_str_add_anim;
extern const bcstring be_const_str_add_cb_event_closure;
@ -264,6 +287,7 @@ extern const bcstring be_const_str_allocated;
extern const bcstring be_const_str_alternate;
extern const bcstring be_const_str_animate;
extern const bcstring be_const_str_animators;
extern const bcstring be_const_str_app;
extern const bcstring be_const_str_arc_dsc;
extern const bcstring be_const_str_arch;
extern const bcstring be_const_str_area;
@ -353,11 +377,17 @@ extern const bcstring be_const_str_content_stop;
extern const bcstring be_const_str_continue;
extern const bcstring be_const_str_coord_arr;
extern const bcstring be_const_str_copy;
extern const bcstring be_const_str_coredump;
extern const bcstring be_const_str_cos;
extern const bcstring be_const_str_cosh;
extern const bcstring be_const_str_couldn_X27t_X20not_X20initialize_X20noepixelbus;
extern const bcstring be_const_str_count;
extern const bcstring be_const_str_counters;
extern const bcstring be_const_str_crc;
extern const bcstring be_const_str_crc16;
extern const bcstring be_const_str_crc32;
extern const bcstring be_const_str_crc32_ota_seq;
extern const bcstring be_const_str_crc8;
extern const bcstring be_const_str_create_custom_widget;
extern const bcstring be_const_str_create_matrix;
extern const bcstring be_const_str_create_segment;
@ -366,6 +396,7 @@ extern const bcstring be_const_str_ctor;
extern const bcstring be_const_str_ctypes_bytes;
extern const bcstring be_const_str_ctypes_bytes_dyn;
extern const bcstring be_const_str_dac_voltage;
extern const bcstring be_const_str_data;
extern const bcstring be_const_str_day;
extern const bcstring be_const_str_debug;
extern const bcstring be_const_str_decode;
@ -403,6 +434,7 @@ extern const bcstring be_const_str_driver_name;
extern const bcstring be_const_str_dump;
extern const bcstring be_const_str_duration;
extern const bcstring be_const_str_editable;
extern const bcstring be_const_str_efuse_em;
extern const bcstring be_const_str_elements_X20must_X20be_X20a_X20lv_point;
extern const bcstring be_const_str_elif;
extern const bcstring be_const_str_else;
@ -413,6 +445,7 @@ extern const bcstring be_const_str_energy_struct;
extern const bcstring be_const_str_engine;
extern const bcstring be_const_str_erase;
extern const bcstring be_const_str_escape;
extern const bcstring be_const_str_esphttpd;
extern const bcstring be_const_str_eth;
extern const bcstring be_const_str_event;
extern const bcstring be_const_str_event_cb;
@ -428,9 +461,11 @@ extern const bcstring be_const_str_exec_tele;
extern const bcstring be_const_str_exists;
extern const bcstring be_const_str_exp;
extern const bcstring be_const_str_f;
extern const bcstring be_const_str_factory;
extern const bcstring be_const_str_false;
extern const bcstring be_const_str_fast_loop;
extern const bcstring be_const_str_fast_loop_enabled;
extern const bcstring be_const_str_fat;
extern const bcstring be_const_str_file;
extern const bcstring be_const_str_file_X20extension_X20is_X20not_X20_X27_X2Ebe_X27_X20or_X20_X27_X2Ebec_X27;
extern const bcstring be_const_str_files;
@ -438,6 +473,8 @@ extern const bcstring be_const_str_find;
extern const bcstring be_const_str_find_key_i;
extern const bcstring be_const_str_find_op;
extern const bcstring be_const_str_finish;
extern const bcstring be_const_str_flags;
extern const bcstring be_const_str_flash;
extern const bcstring be_const_str_floor;
extern const bcstring be_const_str_flush;
extern const bcstring be_const_str_font_embedded;
@ -460,6 +497,7 @@ extern const bcstring be_const_str_gc;
extern const bcstring be_const_str_gen_cb;
extern const bcstring be_const_str_get;
extern const bcstring be_const_str_get_MAC;
extern const bcstring be_const_str_get_active;
extern const bcstring be_const_str_get_alternate;
extern const bcstring be_const_str_get_aps_voltage;
extern const bcstring be_const_str_get_bat_charge_current;
@ -476,12 +514,14 @@ extern const bcstring be_const_str_get_event_cb;
extern const bcstring be_const_str_get_free_heap;
extern const bcstring be_const_str_get_height;
extern const bcstring be_const_str_get_hor_res;
extern const bcstring be_const_str_get_image_size;
extern const bcstring be_const_str_get_input_power_status;
extern const bcstring be_const_str_get_light;
extern const bcstring be_const_str_get_log;
extern const bcstring be_const_str_get_name;
extern const bcstring be_const_str_get_object_from_ptr;
extern const bcstring be_const_str_get_option;
extern const bcstring be_const_str_get_ota_slot;
extern const bcstring be_const_str_get_percentage;
extern const bcstring be_const_str_get_pixel_color;
extern const bcstring be_const_str_get_power;
@ -540,12 +580,17 @@ extern const bcstring be_const_str_int64;
extern const bcstring be_const_str_internal_error;
extern const bcstring be_const_str_introspect;
extern const bcstring be_const_str_invalid_X20GPIO_X20number;
extern const bcstring be_const_str_invalid_X20magic_X20number_X20_X2502X;
extern const bcstring be_const_str_invalidate;
extern const bcstring be_const_str_invalidate_spiffs;
extern const bcstring be_const_str_io_error;
extern const bcstring be_const_str_ip;
extern const bcstring be_const_str_is_dirty;
extern const bcstring be_const_str_is_factory;
extern const bcstring be_const_str_is_first_time;
extern const bcstring be_const_str_is_ota;
extern const bcstring be_const_str_is_running;
extern const bcstring be_const_str_is_spiffs;
extern const bcstring be_const_str_isinstance;
extern const bcstring be_const_str_ismethod;
extern const bcstring be_const_str_isnan;
@ -575,6 +620,7 @@ extern const bcstring be_const_str_list_handlers;
extern const bcstring be_const_str_listdir;
extern const bcstring be_const_str_load;
extern const bcstring be_const_str_load_freetype_font;
extern const bcstring be_const_str_load_otadata;
extern const bcstring be_const_str_load_templates;
extern const bcstring be_const_str_local;
extern const bcstring be_const_str_log;
@ -610,6 +656,8 @@ extern const bcstring be_const_str_manuf;
extern const bcstring be_const_str_map;
extern const bcstring be_const_str_math;
extern const bcstring be_const_str_matrix;
extern const bcstring be_const_str_maxota;
extern const bcstring be_const_str_md5;
extern const bcstring be_const_str_member;
extern const bcstring be_const_str_members;
extern const bcstring be_const_str_memory;
@ -621,6 +669,9 @@ extern const bcstring be_const_str_model;
extern const bcstring be_const_str_module;
extern const bcstring be_const_str_month;
extern const bcstring be_const_str_montserrat_font;
extern const bcstring be_const_str_mqtt;
extern const bcstring be_const_str_mqtt_data;
extern const bcstring be_const_str_mqtt_listener;
extern const bcstring be_const_str_name;
extern const bcstring be_const_str_nan;
extern const bcstring be_const_str_next;
@ -631,6 +682,8 @@ extern const bcstring be_const_str_no_X20more_X20RMT_X20channel_X20available;
extern const bcstring be_const_str_now;
extern const bcstring be_const_str_null_cb;
extern const bcstring be_const_str_number;
extern const bcstring be_const_str_nvs;
extern const bcstring be_const_str_nvskeys;
extern const bcstring be_const_str_o;
extern const bcstring be_const_str_obj;
extern const bcstring be_const_str_obj_class_create_obj;
@ -641,12 +694,17 @@ extern const bcstring be_const_str_on;
extern const bcstring be_const_str_onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E;
extern const bcstring be_const_str_onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20change_X20the_X20current_X20configuration_X20and_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E;
extern const bcstring be_const_str_open;
extern const bcstring be_const_str_ota;
extern const bcstring be_const_str_ota_max;
extern const bcstring be_const_str_otadata;
extern const bcstring be_const_str_out_X20of_X20range;
extern const bcstring be_const_str_p1;
extern const bcstring be_const_str_p2;
extern const bcstring be_const_str_page_autoconf_ctl;
extern const bcstring be_const_str_page_autoconf_mgr;
extern const bcstring be_const_str_param;
extern const bcstring be_const_str_parse;
extern const bcstring be_const_str_partition_core;
extern const bcstring be_const_str_path;
extern const bcstring be_const_str_pc;
extern const bcstring be_const_str_pc_abs;
@ -655,6 +713,7 @@ extern const bcstring be_const_str_pct;
extern const bcstring be_const_str_percentage;
extern const bcstring be_const_str_persist;
extern const bcstring be_const_str_persist_X2E_p_X20is_X20not_X20a_X20map;
extern const bcstring be_const_str_phy;
extern const bcstring be_const_str_pi;
extern const bcstring be_const_str_pin;
extern const bcstring be_const_str_pin_mode;
@ -683,6 +742,7 @@ extern const bcstring be_const_str_rad;
extern const bcstring be_const_str_raise;
extern const bcstring be_const_str_rand;
extern const bcstring be_const_str_range;
extern const bcstring be_const_str_raw;
extern const bcstring be_const_str_read;
extern const bcstring be_const_str_read12;
extern const bcstring be_const_str_read13;
@ -710,6 +770,7 @@ extern const bcstring be_const_str_remove_driver;
extern const bcstring be_const_str_remove_light;
extern const bcstring be_const_str_remove_rule;
extern const bcstring be_const_str_remove_timer;
extern const bcstring be_const_str_remove_trailing_zeroes;
extern const bcstring be_const_str_reset;
extern const bcstring be_const_str_reset_search;
extern const bcstring be_const_str_resize;
@ -724,6 +785,7 @@ extern const bcstring be_const_str_return;
extern const bcstring be_const_str_return_X20code_X3D_X25i;
extern const bcstring be_const_str_reverse;
extern const bcstring be_const_str_reverse_gamma10;
extern const bcstring be_const_str_rollback;
extern const bcstring be_const_str_rotate;
extern const bcstring be_const_str_round_end;
extern const bcstring be_const_str_round_start;
@ -748,9 +810,12 @@ extern const bcstring be_const_str_seg7_font;
extern const bcstring be_const_str_select;
extern const bcstring be_const_str_send;
extern const bcstring be_const_str_send_multicast;
extern const bcstring be_const_str_seq0;
extern const bcstring be_const_str_seq1;
extern const bcstring be_const_str_serial;
extern const bcstring be_const_str_set;
extern const bcstring be_const_str_set_MAC;
extern const bcstring be_const_str_set_active;
extern const bcstring be_const_str_set_align;
extern const bcstring be_const_str_set_alternate;
extern const bcstring be_const_str_set_auth;
@ -776,6 +841,7 @@ extern const bcstring be_const_str_set_light;
extern const bcstring be_const_str_set_matrix_pixel_color;
extern const bcstring be_const_str_set_mode_ct;
extern const bcstring be_const_str_set_mode_rgb;
extern const bcstring be_const_str_set_ota_max;
extern const bcstring be_const_str_set_percentage;
extern const bcstring be_const_str_set_pixel_color;
extern const bcstring be_const_str_set_power;
@ -824,7 +890,9 @@ extern const bcstring be_const_str_sin;
extern const bcstring be_const_str_sinh;
extern const bcstring be_const_str_size;
extern const bcstring be_const_str_skip;
extern const bcstring be_const_str_slots;
extern const bcstring be_const_str_solidified;
extern const bcstring be_const_str_spiffs;
extern const bcstring be_const_str_splash;
extern const bcstring be_const_str_splash_init;
extern const bcstring be_const_str_splash_remove;
@ -844,8 +912,10 @@ extern const bcstring be_const_str_strip;
extern const bcstring be_const_str_strptime;
extern const bcstring be_const_str_style_prop_arr;
extern const bcstring be_const_str_subscribe;
extern const bcstring be_const_str_subtype;
extern const bcstring be_const_str_success;
extern const bcstring be_const_str_super;
extern const bcstring be_const_str_switch_factory;
extern const bcstring be_const_str_sys;
extern const bcstring be_const_str_tag;
extern const bcstring be_const_str_tan;
@ -858,6 +928,7 @@ extern const bcstring be_const_str_tasmota_X2Eset_light_X28_X29_X20is_X20depreca
extern const bcstring be_const_str_tasmota_log_reader;
extern const bcstring be_const_str_tcpclient;
extern const bcstring be_const_str_tele;
extern const bcstring be_const_str_test;
extern const bcstring be_const_str_the_X20second_X20argument_X20is_X20not_X20a_X20function;
extern const bcstring be_const_str_time_dump;
extern const bcstring be_const_str_time_reached;
@ -870,6 +941,7 @@ extern const bcstring be_const_str_toint;
extern const bcstring be_const_str_tolower;
extern const bcstring be_const_str_tomap;
extern const bcstring be_const_str_top;
extern const bcstring be_const_str_topic;
extern const bcstring be_const_str_toptr;
extern const bcstring be_const_str_tostring;
extern const bcstring be_const_str_touch_update;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libcrc_map) {
{ be_const_key(crc32, 1), be_const_ctype_func(c_crc32) },
{ be_const_key(crc8, 2), be_const_ctype_func(c_crc8) },
{ be_const_key(crc16, -1), be_const_ctype_func(c_crc16) },
};
static be_define_const_map(
m_libcrc_map,
3
);
static be_define_const_module(
m_libcrc,
"crc"
);
BE_EXPORT_VARIABLE be_define_const_native_module(crc);

View File

@ -1,14 +1,15 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libflash_map) {
{ be_const_key(read, -1), be_const_func(p_flash_read) },
{ be_const_key(erase, -1), be_const_func(p_flash_erase) },
{ be_const_key(write, -1), be_const_func(p_flash_write) },
{ be_const_key(factory, 2), be_const_ctype_func(p_factory) },
{ be_const_key(erase, 3), be_const_func(p_flash_erase) },
{ be_const_key(read, -1), be_const_func(p_flash_read) },
};
static be_define_const_map(
m_libflash_map,
3
4
);
static be_define_const_module(

View File

@ -1,14 +1,15 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libmqtt_map) {
{ be_const_key(unsubscribe, -1), be_const_ctype_func(be_mqtt_unsubscribe) },
{ be_const_key(subscribe, -1), be_const_ctype_func(be_mqtt_subscribe) },
{ be_const_key(publish, 1), be_const_func(be_mqtt_publish) },
{ be_const_key(publish, -1), be_const_func(be_mqtt_publish) },
{ be_const_key(_subscribe, -1), be_const_ctype_func(be_mqtt_subscribe) },
{ be_const_key(unsubscribe, 1), be_const_ctype_func(be_mqtt_unsubscribe) },
{ be_const_key(subscribe, -1), be_const_closure(subscribe_closure) },
};
static be_define_const_map(
m_libmqtt_map,
3
4
);
static be_define_const_module(

View File

@ -511,7 +511,7 @@ static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, int buil
size_t id_len = toidentifier_length(class_name);
char id_buf[id_len];
toidentifier(id_buf, class_name);
logfmt(" &be_const_str_%s,\n", id_buf);
logfmt(" (bstring*) &be_const_str_%s\n", id_buf);
} else {
size_t id_len = toliteral_length(class_name);
char id_buf[id_len];

View File

@ -0,0 +1,88 @@
/********************************************************************
* Berry module `webserver`
*
* To use: `import webserver`
*
* Allows to respond to HTTP request
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
#include "rom/crc.h"
uint32_t c_crc32(uint32_t crc, const uint8_t* buf, size_t size) {
return crc32_le(crc, buf, size);
}
BE_FUNC_CTYPE_DECLARE(c_crc32, "i", "i(bytes)~")
uint32_t c_crc16(uint32_t crc, const uint8_t* buf, size_t size) {
return crc16_le(crc, buf, size);
}
BE_FUNC_CTYPE_DECLARE(c_crc16, "i", "i(bytes)~")
uint32_t c_crc8(uint32_t crc, const uint8_t* buf, size_t size) {
return crc8_le(crc, buf, size);
}
BE_FUNC_CTYPE_DECLARE(c_crc8, "i", "i(bytes)~")
// const uint32_t crc32_tab[] = {
// 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
// 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
// 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
// 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
// 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
// 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
// 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
// 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
// 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
// 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
// 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
// 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
// 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
// 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
// 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
// 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
// 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
// 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
// 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
// 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
// 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
// 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
// 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
// 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
// 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
// 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
// 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
// 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
// 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
// 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
// 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
// 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
// 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
// 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
// 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
// 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
// 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
// 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
// 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
// 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
// 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
// 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
// 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
// };
// uint32_t c_crc32(uint32_t crc, const uint8_t *p, size_t size) {
// crc ^= ~0U;
// while (size--)
// crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
// return crc ^ ~0U;
// }
/* @const_object_info_begin
module crc (scope: global) {
crc32, ctype_func(c_crc32)
crc16, ctype_func(c_crc16)
crc8, ctype_func(c_crc8)
}
@const_object_info_end */
#include "be_fixed_crc.h"

View File

@ -6,6 +6,18 @@
* Allows to respond to HTTP request
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
#include "esp_partition.h"
// Forces the next restart to use the `factory` partition if any is present
void p_factory(void) {
const esp_partition_t *otadata_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
if (otadata_partition) {
esp_partition_erase_range(otadata_partition, 0, SPI_FLASH_SEC_SIZE * 2);
}
}
BE_FUNC_CTYPE_DECLARE(p_factory, "", "");
extern int p_flash_read(bvm *vm);
extern int p_flash_write(bvm *vm);
@ -16,6 +28,8 @@ module flash (scope: global) {
read, func(p_flash_read)
write, func(p_flash_write)
erase, func(p_flash_erase)
factory, ctype_func(p_factory)
}
@const_object_info_end */
#include "be_fixed_flash.h"

View File

@ -0,0 +1,288 @@
/********************************************************************
* Berry module `mqtt`
*
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
/* Embedded code */
/*
def subscribe(topic, closure)
class mqtt_listener
var topic
var closure
def init(topic, closure)
import string
self.topic = string.split(topic, '/')
self.closure = closure
tasmota.add_driver(self)
end
def mqtt_data(topic, idx, payload_s, payload_b)
# check if the topic matches the patter
import string
var topic_elts = string.split(topic, '/')
var topic_sz = size(topic_elts)
var pat = self.topic
var pat_sz = size(pat)
var i = 0
while i < pat_sz
var pat_elt = pat[i]
if pat_elt == '#'
# joker, munch whatever is left
# '#' is supposed to be the last character of the topic (we don't check it)
break
elif i >= topic_sz
# the topic is too short - no match
return false
elif pat_elt == '+'
# pass
elif pat_elt != topic_elts[i]
# topic element are different - no match
return false
end
i += 1
end
if i >= pat_sz && pat_sz != topic_sz
# the topic is too long and the pattern did not finish with '#' - no match
return false
end
var cl = self.closure
var ret = cl(topic, idx, payload_s, payload_b)
if ret == nil ret = true end # return true if the return value is forgotten
return ret
end
end
import mqtt
mqtt._subscribe(topic)
if type(closure) == 'function'
tasmota.check_not_method(closure)
mqtt_listener(topic, closure)
end
end
*/
/********************************************************************
** Solidified function: mqtt_data
********************************************************************/
be_local_closure(mqtt_listener_mqtt_data, /* name */
be_nested_proto(
17, /* nstack */
5, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 9]) { /* constants */
/* K0 */ be_nested_str(string),
/* K1 */ be_nested_str(split),
/* K2 */ be_nested_str(_X2F),
/* K3 */ be_nested_str(topic),
/* K4 */ be_const_int(0),
/* K5 */ be_nested_str(_X23),
/* K6 */ be_nested_str(_X2B),
/* K7 */ be_const_int(1),
/* K8 */ be_nested_str(closure),
}),
&be_const_str_mqtt_data,
&be_const_str_solidified,
( &(const binstruction[53]) { /* code */
0xA4160000, // 0000 IMPORT R5 K0
0x8C180B01, // 0001 GETMET R6 R5 K1
0x5C200200, // 0002 MOVE R8 R1
0x58240002, // 0003 LDCONST R9 K2
0x7C180600, // 0004 CALL R6 3
0x601C000C, // 0005 GETGBL R7 G12
0x5C200C00, // 0006 MOVE R8 R6
0x7C1C0200, // 0007 CALL R7 1
0x88200103, // 0008 GETMBR R8 R0 K3
0x6024000C, // 0009 GETGBL R9 G12
0x5C281000, // 000A MOVE R10 R8
0x7C240200, // 000B CALL R9 1
0x58280004, // 000C LDCONST R10 K4
0x142C1409, // 000D LT R11 R10 R9
0x782E0013, // 000E JMPF R11 #0023
0x942C100A, // 000F GETIDX R11 R8 R10
0x1C301705, // 0010 EQ R12 R11 K5
0x78320001, // 0011 JMPF R12 #0014
0x7002000F, // 0012 JMP #0023
0x7002000C, // 0013 JMP #0021
0x28301407, // 0014 GE R12 R10 R7
0x78320002, // 0015 JMPF R12 #0019
0x50300000, // 0016 LDBOOL R12 0 0
0x80041800, // 0017 RET 1 R12
0x70020007, // 0018 JMP #0021
0x1C301706, // 0019 EQ R12 R11 K6
0x78320000, // 001A JMPF R12 #001C
0x70020004, // 001B JMP #0021
0x94300C0A, // 001C GETIDX R12 R6 R10
0x2030160C, // 001D NE R12 R11 R12
0x78320001, // 001E JMPF R12 #0021
0x50300000, // 001F LDBOOL R12 0 0
0x80041800, // 0020 RET 1 R12
0x00281507, // 0021 ADD R10 R10 K7
0x7001FFE9, // 0022 JMP #000D
0x282C1409, // 0023 GE R11 R10 R9
0x782E0003, // 0024 JMPF R11 #0029
0x202C1207, // 0025 NE R11 R9 R7
0x782E0001, // 0026 JMPF R11 #0029
0x502C0000, // 0027 LDBOOL R11 0 0
0x80041600, // 0028 RET 1 R11
0x882C0108, // 0029 GETMBR R11 R0 K8
0x5C301600, // 002A MOVE R12 R11
0x5C340200, // 002B MOVE R13 R1
0x5C380400, // 002C MOVE R14 R2
0x5C3C0600, // 002D MOVE R15 R3
0x5C400800, // 002E MOVE R16 R4
0x7C300800, // 002F CALL R12 4
0x4C340000, // 0030 LDNIL R13
0x1C34180D, // 0031 EQ R13 R12 R13
0x78360000, // 0032 JMPF R13 #0034
0x50300200, // 0033 LDBOOL R12 1 0
0x80041800, // 0034 RET 1 R12
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(mqtt_listener_init, /* name */
be_nested_proto(
8, /* nstack */
3, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 7]) { /* constants */
/* K0 */ be_nested_str(string),
/* K1 */ be_nested_str(topic),
/* K2 */ be_nested_str(split),
/* K3 */ be_nested_str(_X2F),
/* K4 */ be_nested_str(closure),
/* K5 */ be_nested_str(tasmota),
/* K6 */ be_nested_str(add_driver),
}),
&be_const_str_init,
&be_const_str_solidified,
( &(const binstruction[12]) { /* code */
0xA40E0000, // 0000 IMPORT R3 K0
0x8C100702, // 0001 GETMET R4 R3 K2
0x5C180200, // 0002 MOVE R6 R1
0x581C0003, // 0003 LDCONST R7 K3
0x7C100600, // 0004 CALL R4 3
0x90020204, // 0005 SETMBR R0 K1 R4
0x90020802, // 0006 SETMBR R0 K4 R2
0xB8120A00, // 0007 GETNGBL R4 K5
0x8C100906, // 0008 GETMET R4 R4 K6
0x5C180000, // 0009 MOVE R6 R0
0x7C100400, // 000A CALL R4 2
0x80000000, // 000B RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: mqtt_listener
********************************************************************/
be_local_class(mqtt_listener,
2,
NULL,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key(topic, 1), be_const_var(0) },
{ be_const_key(mqtt_data, -1), be_const_closure(mqtt_listener_mqtt_data_closure) },
{ be_const_key(closure, -1), be_const_var(1) },
{ be_const_key(init, -1), be_const_closure(mqtt_listener_init_closure) },
})),
(bstring*) &be_const_str_mqtt_listener
);
/********************************************************************
** Solidified function: subscribe
********************************************************************/
be_local_closure(subscribe, /* name */
be_nested_proto(
7, /* nstack */
2, /* argc */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 6]) { /* constants */
/* K0 */ be_const_class(be_class_mqtt_listener),
/* K1 */ be_nested_str(mqtt),
/* K2 */ be_nested_str(_subscribe),
/* K3 */ be_nested_str(function),
/* K4 */ be_nested_str(tasmota),
/* K5 */ be_nested_str(check_not_method),
}),
&be_const_str_subscribe,
&be_const_str_solidified,
( &(const binstruction[20]) { /* code */
0x58080000, // 0000 LDCONST R2 K0
0xB4000000, // 0001 CLASS K0
0xA40E0200, // 0002 IMPORT R3 K1
0x8C100702, // 0003 GETMET R4 R3 K2
0x5C180000, // 0004 MOVE R6 R0
0x7C100400, // 0005 CALL R4 2
0x60100004, // 0006 GETGBL R4 G4
0x5C140200, // 0007 MOVE R5 R1
0x7C100200, // 0008 CALL R4 1
0x1C100903, // 0009 EQ R4 R4 K3
0x78120007, // 000A JMPF R4 #0013
0xB8120800, // 000B GETNGBL R4 K4
0x8C100905, // 000C GETMET R4 R4 K5
0x5C180200, // 000D MOVE R6 R1
0x7C100400, // 000E CALL R4 2
0x5C100400, // 000F MOVE R4 R2
0x5C140000, // 0010 MOVE R5 R0
0x5C180200, // 0011 MOVE R6 R1
0x7C100400, // 0012 CALL R4 2
0x80000000, // 0013 RET 0
})
)
);
/*******************************************************************/
extern int be_mqtt_publish(bvm *vm);
extern void be_mqtt_subscribe(const char* topic); BE_FUNC_CTYPE_DECLARE(be_mqtt_subscribe, "", "s")
extern void be_mqtt_unsubscribe(const char* topic); BE_FUNC_CTYPE_DECLARE(be_mqtt_unsubscribe, "", "s")
/* @const_object_info_begin
module mqtt (scope: global) {
publish, func(be_mqtt_publish)
subscribe, closure(subscribe_closure)
_subscribe, ctype_func(be_mqtt_subscribe)
unsubscribe, ctype_func(be_mqtt_unsubscribe)
}
@const_object_info_end */
#include "be_fixed_mqtt.h"

View File

@ -1,21 +0,0 @@
/********************************************************************
* Berry module `mqtt`
*
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
extern int be_mqtt_publish(bvm *vm);
extern void be_mqtt_subscribe(const char* topic); BE_FUNC_CTYPE_DECLARE(be_mqtt_subscribe, "", "s")
extern void be_mqtt_unsubscribe(const char* topic); BE_FUNC_CTYPE_DECLARE(be_mqtt_unsubscribe, "", "s")
/* @const_object_info_begin
module mqtt (scope: global) {
publish, func(be_mqtt_publish)
subscribe, ctype_func(be_mqtt_subscribe)
unsubscribe, ctype_func(be_mqtt_unsubscribe)
}
@const_object_info_end */
#include "be_fixed_mqtt.h"

File diff suppressed because it is too large Load Diff

View File

@ -741,7 +741,7 @@ be_local_closure(Tasmota_add_fast_loop, /* name */
********************************************************************/
be_local_closure(Tasmota_event, /* name */
be_nested_proto(
20, /* nstack */
21, /* nstack */
6, /* argc */
2, /* varg */
0, /* has upvals */
@ -749,37 +749,38 @@ be_local_closure(Tasmota_event, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[26]) { /* constants */
( &(const bvalue[27]) { /* constants */
/* K0 */ be_nested_str(introspect),
/* K1 */ be_nested_str(string),
/* K2 */ be_nested_str(every_50ms),
/* K3 */ be_nested_str(run_deferred),
/* K4 */ be_nested_str(every_250ms),
/* K5 */ be_nested_str(run_cron),
/* K6 */ be_nested_str(cmd),
/* K7 */ be_nested_str(exec_cmd),
/* K8 */ be_nested_str(tele),
/* K9 */ be_nested_str(exec_tele),
/* K10 */ be_nested_str(rule),
/* K11 */ be_nested_str(exec_rules),
/* K12 */ be_nested_str(gc),
/* K13 */ be_nested_str(_drivers),
/* K14 */ be_const_int(0),
/* K15 */ be_nested_str(get),
/* K16 */ be_nested_str(function),
/* K17 */ be_nested_str(format),
/* K18 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s),
/* K19 */ be_nested_str(_debug_present),
/* K20 */ be_nested_str(debug),
/* K21 */ be_nested_str(traceback),
/* K22 */ be_const_int(1),
/* K23 */ be_nested_str(save_before_restart),
/* K24 */ be_nested_str(persist),
/* K25 */ be_nested_str(save),
/* K6 */ be_nested_str(mqtt_data),
/* K7 */ be_nested_str(cmd),
/* K8 */ be_nested_str(exec_cmd),
/* K9 */ be_nested_str(tele),
/* K10 */ be_nested_str(exec_tele),
/* K11 */ be_nested_str(rule),
/* K12 */ be_nested_str(exec_rules),
/* K13 */ be_nested_str(gc),
/* K14 */ be_nested_str(_drivers),
/* K15 */ be_const_int(0),
/* K16 */ be_nested_str(get),
/* K17 */ be_nested_str(function),
/* K18 */ be_nested_str(format),
/* K19 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s),
/* K20 */ be_nested_str(_debug_present),
/* K21 */ be_nested_str(debug),
/* K22 */ be_nested_str(traceback),
/* K23 */ be_const_int(1),
/* K24 */ be_nested_str(save_before_restart),
/* K25 */ be_nested_str(persist),
/* K26 */ be_nested_str(save),
}),
&be_const_str_event,
&be_const_str_solidified,
( &(const binstruction[97]) { /* code */
( &(const binstruction[109]) { /* code */
0xA41A0000, // 0000 IMPORT R6 K0
0xA41E0200, // 0001 IMPORT R7 K1
0x1C200302, // 0002 EQ R8 R1 K2
@ -791,92 +792,104 @@ be_local_closure(Tasmota_event, /* name */
0x8C200105, // 0008 GETMET R8 R0 K5
0x7C200200, // 0009 CALL R8 1
0x50200000, // 000A LDBOOL R8 0 0
0x1C240306, // 000B EQ R9 R1 K6
0x78260006, // 000C JMPF R9 #0014
0x8C240107, // 000D GETMET R9 R0 K7
0x5C2C0400, // 000E MOVE R11 R2
0x5C300600, // 000F MOVE R12 R3
0x5C340800, // 0010 MOVE R13 R4
0x7C240800, // 0011 CALL R9 4
0x80041200, // 0012 RET 1 R9
0x70020046, // 0013 JMP #005B
0x1C240308, // 0014 EQ R9 R1 K8
0x78260004, // 0015 JMPF R9 #001B
0x8C240109, // 0016 GETMET R9 R0 K9
0x5C2C0800, // 0017 MOVE R11 R4
0x7C240400, // 0018 CALL R9 2
0x80041200, // 0019 RET 1 R9
0x7002003F, // 001A JMP #005B
0x1C24030A, // 001B EQ R9 R1 K10
0x78260004, // 001C JMPF R9 #0022
0x8C24010B, // 001D GETMET R9 R0 K11
0x5C2C0800, // 001E MOVE R11 R4
0x7C240400, // 001F CALL R9 2
0x80041200, // 0020 RET 1 R9
0x70020038, // 0021 JMP #005B
0x1C24030C, // 0022 EQ R9 R1 K12
0x78260003, // 0023 JMPF R9 #0028
0x8C24010C, // 0024 GETMET R9 R0 K12
0x7C240200, // 0025 CALL R9 1
0x80041200, // 0026 RET 1 R9
0x70020032, // 0027 JMP #005B
0x8824010D, // 0028 GETMBR R9 R0 K13
0x78260030, // 0029 JMPF R9 #005B
0x5824000E, // 002A LDCONST R9 K14
0x6028000C, // 002B GETGBL R10 G12
0x882C010D, // 002C GETMBR R11 R0 K13
0x7C280200, // 002D CALL R10 1
0x1428120A, // 002E LT R10 R9 R10
0x782A002A, // 002F JMPF R10 #005B
0x8828010D, // 0030 GETMBR R10 R0 K13
0x94281409, // 0031 GETIDX R10 R10 R9
0x8C2C0D0F, // 0032 GETMET R11 R6 K15
0x5C341400, // 0033 MOVE R13 R10
0x5C380200, // 0034 MOVE R14 R1
0x7C2C0600, // 0035 CALL R11 3
0x60300004, // 0036 GETGBL R12 G4
0x5C341600, // 0037 MOVE R13 R11
0x7C300200, // 0038 CALL R12 1
0x1C301910, // 0039 EQ R12 R12 K16
0x7832001D, // 003A JMPF R12 #0059
0xA802000C, // 003B EXBLK 0 #0049
0x5C301600, // 003C MOVE R12 R11
0x5C341400, // 003D MOVE R13 R10
0x5C380400, // 003E MOVE R14 R2
0x5C3C0600, // 003F MOVE R15 R3
0x5C400800, // 0040 MOVE R16 R4
0x5C440A00, // 0041 MOVE R17 R5
0x7C300A00, // 0042 CALL R12 5
0x5C201800, // 0043 MOVE R8 R12
0x78220001, // 0044 JMPF R8 #0047
0xA8040001, // 0045 EXBLK 1 1
0x70020013, // 0046 JMP #005B
0xA8040001, // 0047 EXBLK 1 1
0x7002000F, // 0048 JMP #0059
0xAC300002, // 0049 CATCH R12 0 2
0x7002000C, // 004A JMP #0058
0x60380001, // 004B GETGBL R14 G1
0x8C3C0F11, // 004C GETMET R15 R7 K17
0x58440012, // 004D LDCONST R17 K18
0x5C481800, // 004E MOVE R18 R12
0x5C4C1A00, // 004F MOVE R19 R13
0x7C3C0800, // 0050 CALL R15 4
0x7C380200, // 0051 CALL R14 1
0x88380113, // 0052 GETMBR R14 R0 K19
0x783A0002, // 0053 JMPF R14 #0057
0xA43A2800, // 0054 IMPORT R14 K20
0x8C3C1D15, // 0055 GETMET R15 R14 K21
0x7C3C0200, // 0056 CALL R15 1
0x70020000, // 0057 JMP #0059
0xB0080000, // 0058 RAISE 2 R0 R0
0x00241316, // 0059 ADD R9 R9 K22
0x7001FFCF, // 005A JMP #002B
0x1C240317, // 005B EQ R9 R1 K23
0x78260002, // 005C JMPF R9 #0060
0xA4263000, // 005D IMPORT R9 K24
0x8C281319, // 005E GETMET R10 R9 K25
0x7C280200, // 005F CALL R10 1
0x80041000, // 0060 RET 1 R8
0x50240000, // 000B LDBOOL R9 0 0
0x1C280306, // 000C EQ R10 R1 K6
0x782A0000, // 000D JMPF R10 #000F
0x50240200, // 000E LDBOOL R9 1 0
0x1C280307, // 000F EQ R10 R1 K7
0x782A0006, // 0010 JMPF R10 #0018
0x8C280108, // 0011 GETMET R10 R0 K8
0x5C300400, // 0012 MOVE R12 R2
0x5C340600, // 0013 MOVE R13 R3
0x5C380800, // 0014 MOVE R14 R4
0x7C280800, // 0015 CALL R10 4
0x80041400, // 0016 RET 1 R10
0x7002004E, // 0017 JMP #0067
0x1C280309, // 0018 EQ R10 R1 K9
0x782A0004, // 0019 JMPF R10 #001F
0x8C28010A, // 001A GETMET R10 R0 K10
0x5C300800, // 001B MOVE R12 R4
0x7C280400, // 001C CALL R10 2
0x80041400, // 001D RET 1 R10
0x70020047, // 001E JMP #0067
0x1C28030B, // 001F EQ R10 R1 K11
0x782A0007, // 0020 JMPF R10 #0029
0x8C28010C, // 0021 GETMET R10 R0 K12
0x5C300800, // 0022 MOVE R12 R4
0x60340017, // 0023 GETGBL R13 G23
0x5C380600, // 0024 MOVE R14 R3
0x7C340200, // 0025 CALL R13 1
0x7C280600, // 0026 CALL R10 3
0x80041400, // 0027 RET 1 R10
0x7002003D, // 0028 JMP #0067
0x1C28030D, // 0029 EQ R10 R1 K13
0x782A0003, // 002A JMPF R10 #002F
0x8C28010D, // 002B GETMET R10 R0 K13
0x7C280200, // 002C CALL R10 1
0x80041400, // 002D RET 1 R10
0x70020037, // 002E JMP #0067
0x8828010E, // 002F GETMBR R10 R0 K14
0x782A0035, // 0030 JMPF R10 #0067
0x5828000F, // 0031 LDCONST R10 K15
0x602C000C, // 0032 GETGBL R11 G12
0x8830010E, // 0033 GETMBR R12 R0 K14
0x7C2C0200, // 0034 CALL R11 1
0x142C140B, // 0035 LT R11 R10 R11
0x782E002F, // 0036 JMPF R11 #0067
0x882C010E, // 0037 GETMBR R11 R0 K14
0x942C160A, // 0038 GETIDX R11 R11 R10
0x8C300D10, // 0039 GETMET R12 R6 K16
0x5C381600, // 003A MOVE R14 R11
0x5C3C0200, // 003B MOVE R15 R1
0x7C300600, // 003C CALL R12 3
0x60340004, // 003D GETGBL R13 G4
0x5C381800, // 003E MOVE R14 R12
0x7C340200, // 003F CALL R13 1
0x1C341B11, // 0040 EQ R13 R13 K17
0x78360022, // 0041 JMPF R13 #0065
0xA8020011, // 0042 EXBLK 0 #0055
0x5C341800, // 0043 MOVE R13 R12
0x5C381600, // 0044 MOVE R14 R11
0x5C3C0400, // 0045 MOVE R15 R2
0x5C400600, // 0046 MOVE R16 R3
0x5C440800, // 0047 MOVE R17 R4
0x5C480A00, // 0048 MOVE R18 R5
0x7C340A00, // 0049 CALL R13 5
0x74360001, // 004A JMPT R13 #004D
0x74220000, // 004B JMPT R8 #004D
0x50200001, // 004C LDBOOL R8 0 1
0x50200200, // 004D LDBOOL R8 1 0
0x78220003, // 004E JMPF R8 #0053
0x5C341200, // 004F MOVE R13 R9
0x74360001, // 0050 JMPT R13 #0053
0xA8040001, // 0051 EXBLK 1 1
0x70020013, // 0052 JMP #0067
0xA8040001, // 0053 EXBLK 1 1
0x7002000F, // 0054 JMP #0065
0xAC340002, // 0055 CATCH R13 0 2
0x7002000C, // 0056 JMP #0064
0x603C0001, // 0057 GETGBL R15 G1
0x8C400F12, // 0058 GETMET R16 R7 K18
0x58480013, // 0059 LDCONST R18 K19
0x5C4C1A00, // 005A MOVE R19 R13
0x5C501C00, // 005B MOVE R20 R14
0x7C400800, // 005C CALL R16 4
0x7C3C0200, // 005D CALL R15 1
0x883C0114, // 005E GETMBR R15 R0 K20
0x783E0002, // 005F JMPF R15 #0063
0xA43E2A00, // 0060 IMPORT R15 K21
0x8C401F16, // 0061 GETMET R16 R15 K22
0x7C400200, // 0062 CALL R16 1
0x70020000, // 0063 JMP #0065
0xB0080000, // 0064 RAISE 2 R0 R0
0x00281517, // 0065 ADD R10 R10 K23
0x7001FFCA, // 0066 JMP #0032
0x1C280318, // 0067 EQ R10 R1 K24
0x782A0002, // 0068 JMPF R10 #006C
0xA42A3200, // 0069 IMPORT R10 K25
0x8C2C151A, // 006A GETMET R11 R10 K26
0x7C2C0200, // 006B CALL R11 1
0x80041000, // 006C RET 1 R8
})
)
);
@ -1365,7 +1378,7 @@ be_local_closure(Tasmota_load, /* name */
})
),
be_nested_proto(
9, /* nstack */
11, /* nstack */
1, /* argc */
0, /* varg */
0, /* has upvals */
@ -1377,11 +1390,11 @@ be_local_closure(Tasmota_load, /* name */
/* K0 */ be_nested_str(file),
/* K1 */ be_nested_str(string),
/* K2 */ be_nested_str(format),
/* K3 */ be_nested_str(BRY_X3A_X20failed_X20to_X20load_X20_X27_X25s_X27_X20_X28_X25s_X29),
/* K3 */ be_nested_str(BRY_X3A_X20failed_X20to_X20load_X20_X27_X25s_X27_X20_X28_X25s_X20_X2D_X20_X25s_X29),
}),
&be_const_str_try_compile,
&be_const_str_solidified,
( &(const binstruction[23]) { /* code */
( &(const binstruction[24]) { /* code */
0xA8020007, // 0000 EXBLK 0 #0009
0x6004000D, // 0001 GETGBL R1 G13
0x5C080000, // 0002 MOVE R2 R0
@ -1390,21 +1403,22 @@ be_local_closure(Tasmota_load, /* name */
0xA8040001, // 0005 EXBLK 1 1
0x80040200, // 0006 RET 1 R1
0xA8040001, // 0007 EXBLK 1 1
0x7002000B, // 0008 JMP #0015
0xAC040001, // 0009 CATCH R1 0 1
0x70020008, // 000A JMP #0014
0xA40A0200, // 000B IMPORT R2 K1
0x600C0001, // 000C GETGBL R3 G1
0x8C100502, // 000D GETMET R4 R2 K2
0x58180003, // 000E LDCONST R6 K3
0x5C1C0000, // 000F MOVE R7 R0
0x5C200200, // 0010 MOVE R8 R1
0x7C100800, // 0011 CALL R4 4
0x7C0C0200, // 0012 CALL R3 1
0x70020000, // 0013 JMP #0015
0xB0080000, // 0014 RAISE 2 R0 R0
0x4C040000, // 0015 LDNIL R1
0x80040200, // 0016 RET 1 R1
0x7002000C, // 0008 JMP #0016
0xAC040002, // 0009 CATCH R1 0 2
0x70020009, // 000A JMP #0015
0xA40E0200, // 000B IMPORT R3 K1
0x60100001, // 000C GETGBL R4 G1
0x8C140702, // 000D GETMET R5 R3 K2
0x581C0003, // 000E LDCONST R7 K3
0x5C200000, // 000F MOVE R8 R0
0x5C240200, // 0010 MOVE R9 R1
0x5C280400, // 0011 MOVE R10 R2
0x7C140A00, // 0012 CALL R5 5
0x7C100200, // 0013 CALL R4 1
0x70020000, // 0014 JMP #0016
0xB0080000, // 0015 RAISE 2 R0 R0
0x4C040000, // 0016 LDNIL R1
0x80040200, // 0017 RET 1 R1
})
),
be_nested_proto(
@ -1724,7 +1738,7 @@ be_local_closure(Tasmota_chars_in_string, /* name */
********************************************************************/
be_local_closure(Tasmota_cmd, /* name */
be_nested_proto(
5, /* nstack */
6, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
@ -1739,20 +1753,20 @@ be_local_closure(Tasmota_cmd, /* name */
&be_const_str_cmd,
&be_const_str_solidified,
( &(const binstruction[14]) { /* code */
0x50080200, // 0000 LDBOOL R2 1 0
0x90020002, // 0001 SETMBR R0 K0 R2
0x8C080101, // 0002 GETMET R2 R0 K1
0x5C100200, // 0003 MOVE R4 R1
0x7C080400, // 0004 CALL R2 2
0x4C080000, // 0005 LDNIL R2
0x880C0100, // 0006 GETMBR R3 R0 K0
0x50100200, // 0007 LDBOOL R4 1 0
0x200C0604, // 0008 NE R3 R3 R4
0x780E0000, // 0009 JMPF R3 #000B
0x88080100, // 000A GETMBR R2 R0 K0
0x4C0C0000, // 000B LDNIL R3
0x90020003, // 000C SETMBR R0 K0 R3
0x80040400, // 000D RET 1 R2
0x88080100, // 0000 GETMBR R2 R0 K0
0x500C0200, // 0001 LDBOOL R3 1 0
0x90020003, // 0002 SETMBR R0 K0 R3
0x8C0C0101, // 0003 GETMET R3 R0 K1
0x5C140200, // 0004 MOVE R5 R1
0x7C0C0400, // 0005 CALL R3 2
0x4C0C0000, // 0006 LDNIL R3
0x88100100, // 0007 GETMBR R4 R0 K0
0x50140200, // 0008 LDBOOL R5 1 0
0x20100805, // 0009 NE R4 R4 R5
0x78120000, // 000A JMPF R4 #000C
0x880C0100, // 000B GETMBR R3 R0 K0
0x90020002, // 000C SETMBR R0 K0 R2
0x80040600, // 000D RET 1 R3
})
)
);
@ -1866,8 +1880,8 @@ be_local_closure(Tasmota_add_rule, /* name */
********************************************************************/
be_local_closure(Tasmota_exec_rules, /* name */
be_nested_proto(
12, /* nstack */
2, /* argc */
14, /* nstack */
3, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
@ -1875,8 +1889,8 @@ be_local_closure(Tasmota_exec_rules, /* name */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[12]) { /* constants */
/* K0 */ be_nested_str(_rules),
/* K1 */ be_nested_str(cmd_res),
/* K0 */ be_nested_str(cmd_res),
/* K1 */ be_nested_str(_rules),
/* K2 */ be_nested_str(json),
/* K3 */ be_nested_str(load),
/* K4 */ be_nested_str(log),
@ -1890,55 +1904,57 @@ be_local_closure(Tasmota_exec_rules, /* name */
}),
&be_const_str_exec_rules,
&be_const_str_solidified,
( &(const binstruction[48]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x740A0003, // 0001 JMPT R2 #0006
0x88080101, // 0002 GETMBR R2 R0 K1
0x4C0C0000, // 0003 LDNIL R3
0x20080403, // 0004 NE R2 R2 R3
0x780A0027, // 0005 JMPF R2 #002E
0xA40A0400, // 0006 IMPORT R2 K2
0x8C0C0503, // 0007 GETMET R3 R2 K3
0x5C140200, // 0008 MOVE R5 R1
0x7C0C0400, // 0009 CALL R3 2
0x50100000, // 000A LDBOOL R4 0 0
0x4C140000, // 000B LDNIL R5
0x1C140605, // 000C EQ R5 R3 R5
0x78160004, // 000D JMPF R5 #0013
0x8C140104, // 000E GETMET R5 R0 K4
0x001E0A01, // 000F ADD R7 K5 R1
0x58200006, // 0010 LDCONST R8 K6
0x7C140600, // 0011 CALL R5 3
0x5C0C0200, // 0012 MOVE R3 R1
0x88140101, // 0013 GETMBR R5 R0 K1
0x4C180000, // 0014 LDNIL R6
0x20140A06, // 0015 NE R5 R5 R6
0x78160000, // 0016 JMPF R5 #0018
0x90020203, // 0017 SETMBR R0 K1 R3
0x88140100, // 0018 GETMBR R5 R0 K0
0x78160012, // 0019 JMPF R5 #002D
0x58140007, // 001A LDCONST R5 K7
0x6018000C, // 001B GETGBL R6 G12
0x881C0100, // 001C GETMBR R7 R0 K0
0x7C180200, // 001D CALL R6 1
0x14180A06, // 001E LT R6 R5 R6
0x781A000C, // 001F JMPF R6 #002D
0x88180100, // 0020 GETMBR R6 R0 K0
0x94180C05, // 0021 GETIDX R6 R6 R5
0x8C1C0108, // 0022 GETMET R7 R0 K8
0x5C240600, // 0023 MOVE R9 R3
0x88280D09, // 0024 GETMBR R10 R6 K9
0x882C0D0A, // 0025 GETMBR R11 R6 K10
0x7C1C0800, // 0026 CALL R7 4
0x741E0001, // 0027 JMPT R7 #002A
0x74120000, // 0028 JMPT R4 #002A
0x50100001, // 0029 LDBOOL R4 0 1
0x50100200, // 002A LDBOOL R4 1 0
0x00140B0B, // 002B ADD R5 R5 K11
0x7001FFED, // 002C JMP #001B
0x80040800, // 002D RET 1 R4
0x50080000, // 002E LDBOOL R2 0 0
0x80040400, // 002F RET 1 R2
( &(const binstruction[50]) { /* code */
0x880C0100, // 0000 GETMBR R3 R0 K0
0x88100101, // 0001 GETMBR R4 R0 K1
0x74120002, // 0002 JMPT R4 #0006
0x4C100000, // 0003 LDNIL R4
0x20100604, // 0004 NE R4 R3 R4
0x78120029, // 0005 JMPF R4 #0030
0xA4120400, // 0006 IMPORT R4 K2
0x4C140000, // 0007 LDNIL R5
0x90020005, // 0008 SETMBR R0 K0 R5
0x50140000, // 0009 LDBOOL R5 0 0
0x8C180903, // 000A GETMET R6 R4 K3
0x5C200200, // 000B MOVE R8 R1
0x7C180400, // 000C CALL R6 2
0x4C1C0000, // 000D LDNIL R7
0x1C1C0C07, // 000E EQ R7 R6 R7
0x781E0004, // 000F JMPF R7 #0015
0x8C1C0104, // 0010 GETMET R7 R0 K4
0x00260A01, // 0011 ADD R9 K5 R1
0x58280006, // 0012 LDCONST R10 K6
0x7C1C0600, // 0013 CALL R7 3
0x5C180200, // 0014 MOVE R6 R1
0x780A0014, // 0015 JMPF R2 #002B
0x881C0101, // 0016 GETMBR R7 R0 K1
0x781E0012, // 0017 JMPF R7 #002B
0x581C0007, // 0018 LDCONST R7 K7
0x6020000C, // 0019 GETGBL R8 G12
0x88240101, // 001A GETMBR R9 R0 K1
0x7C200200, // 001B CALL R8 1
0x14200E08, // 001C LT R8 R7 R8
0x7822000C, // 001D JMPF R8 #002B
0x88200101, // 001E GETMBR R8 R0 K1
0x94201007, // 001F GETIDX R8 R8 R7
0x8C240108, // 0020 GETMET R9 R0 K8
0x5C2C0C00, // 0021 MOVE R11 R6
0x88301109, // 0022 GETMBR R12 R8 K9
0x8834110A, // 0023 GETMBR R13 R8 K10
0x7C240800, // 0024 CALL R9 4
0x74260001, // 0025 JMPT R9 #0028
0x74160000, // 0026 JMPT R5 #0028
0x50140001, // 0027 LDBOOL R5 0 1
0x50140200, // 0028 LDBOOL R5 1 0
0x001C0F0B, // 0029 ADD R7 R7 K11
0x7001FFED, // 002A JMP #0019
0x4C1C0000, // 002B LDNIL R7
0x201C0607, // 002C NE R7 R3 R7
0x781E0000, // 002D JMPF R7 #002F
0x90020006, // 002E SETMBR R0 K0 R6
0x80040A00, // 002F RET 1 R5
0x50100000, // 0030 LDBOOL R4 0 0
0x80040800, // 0031 RET 1 R4
})
)
);

View File

@ -199,21 +199,22 @@ class Tasmota
# Run rules, i.e. check each individual rule
# Returns true if at least one rule matched, false if none
def exec_rules(ev_json)
if self._rules || self.cmd_res != nil # if there is a rule handler, or we record rule results
# `exec_rule` is true, then run the rule, else just record value
def exec_rules(ev_json, exec_rule)
var save_cmd_res = self.cmd_res # save initial state (for reentrance)
if self._rules || save_cmd_res != nil # if there is a rule handler, or we record rule results
import json
var ev = json.load(ev_json) # returns nil if invalid JSON
self.cmd_res = nil # disable sunsequent recording of results
var ret = false
var ev = json.load(ev_json) # returns nil if invalid JSON
if ev == nil
self.log('BRY: ERROR, bad json: '+ev_json, 3)
ev = ev_json # revert to string
end
# record the rule payload for tasmota.cmd()
if self.cmd_res != nil
self.cmd_res = ev
end
# try all rule handlers
if self._rules
if exec_rule && self._rules
var i = 0
while i < size(self._rules)
var tr = self._rules[i]
@ -221,6 +222,12 @@ class Tasmota
i += 1
end
end
# record the rule payload for tasmota.cmd()
if save_cmd_res != nil
self.cmd_res = ev
end
return ret
end
return false
@ -373,9 +380,9 @@ class Tasmota
if self._ccmd
import json
var payload_json = json.load(payload)
var cmd_found = self.find_key_i(self._ccmd, cmd)
var cmd_found = self.find_key_i(self._ccmd, cmd) # name of the command as registered (case insensitive search)
if cmd_found != nil
self.resolvecmnd(cmd_found) # set the command name in XdrvMailbox.command
self.resolvecmnd(cmd_found) # set the command name in XdrvMailbox.command as it was registered first
self._ccmd[cmd_found](cmd_found, idx, payload, payload_json)
return true
end
@ -464,9 +471,9 @@ class Tasmota
try
var compiled = compile(f_name, 'file')
return compiled
except .. as e
except .. as e, m
import string
print(string.format('BRY: failed to load \'%s\' (%s)',f_name,e))
print(string.format('BRY: failed to load \'%s\' (%s - %s)',f_name,e,m))
end
return nil
end
@ -633,20 +640,25 @@ class Tasmota
end
var done = false
var keep_going = false # if true, we continue dispatch event if done == true (for mqtt_data)
if event_type == 'mqtt_data'
keep_going = true
end
if event_type=='cmd' return self.exec_cmd(cmd, idx, payload)
elif event_type=='tele' return self.exec_tele(payload)
elif event_type=='rule' return self.exec_rules(payload)
elif event_type=='rule' return self.exec_rules(payload, bool(idx))
elif event_type=='gc' return self.gc()
elif self._drivers
var i = 0
while i < size(self._drivers)
#for d:self._drivers
var d = self._drivers[i]
var f = introspect.get(d, event_type) # try to match a function or method with the same name
if type(f) == 'function'
try
done = f(d, cmd, idx, payload, raw)
if done break end
done = f(d, cmd, idx, payload, raw) || done
if done && !keep_going break end
except .. as e,m
print(string.format("BRY: Exception> '%s' - %s", e, m))
if self._debug_present
@ -690,6 +702,7 @@ class Tasmota
# cmd high-level function
def cmd(command)
var save_cmd_res = self.cmd_res # restore value on exit (for reentrant)
self.cmd_res = true # signal buffer capture
self._cmd(command)
@ -698,7 +711,7 @@ class Tasmota
if self.cmd_res != true # unchanged
ret = self.cmd_res
end
self.cmd_res = nil # clear buffer
self.cmd_res = save_cmd_res # restore previous state
return ret
end

View File

@ -0,0 +1,519 @@
#######################################################################
# Partition manager for ESP32 - ESP32C3 - ESP32S2
#
# use : `import partition_core`
#
# To solidify:
#-
import solidify load("partition_core.be") solidify.dump(partition_core)
-#
# Provides low-level objects and a Web UI
#######################################################################
var partition_core = module('partition_core')
#######################################################################
# Class for a partition table entry
#
# typedef struct {
# uint16_t magic;
# uint8_t type;
# uint8_t subtype;
# uint32_t offset;
# uint32_t size;
# uint8_t label[16];
# uint32_t flags;
# } esp_partition_info_t_simplified;
#
#######################################################################
class Partition_info
var type
var subtype
var start
var size
var label
var flags
#- remove trailing NULL chars from a bytes buffer before converting to string -#
#- Berry strings can contain NULL, but this messes up C-Berry interface -#
static def remove_trailing_zeroes(b)
var sz = size(b)
var i = 0
while i < sz
if b[-1-i] != 0 break end
i += 1
end
if i > 0
b.resize(size(b)-i)
end
return b
end
# Init the Parition information structure, either from a bytes() buffer or an empty if no buffer is provided
def init(raw)
self.type = 0
self.subtype = 0
self.start = 0
self.size = 0
self.label = ''
self.flags = 0
if !issubclass(bytes, raw) # no payload, empty partition information
return
end
#- we have a payload, parse it -#
var magic = raw.get(0,2)
if magic == 0x50AA #- partition entry -#
self.type = raw.get(2,1)
self.subtype = raw.get(3,1)
self.start = raw.get(4,4)
self.size = raw.get(8,4)
self.label = self.remove_trailing_zeroes(raw[12..27]).asstring()
self.flags = raw.get(28,4)
# elif magic == 0xEBEB #- MD5 -#
else
import string
raise "internal_error", string.format("invalid magic number %02X", magic)
end
end
# check if the parition is an OTA partition
# if yes, return OTA number (starting at 0)
# if no, return nil
def is_ota()
var sub_type = self.subtype
if self.type == 0 && (sub_type >= 0x10 && sub_type < 0x20)
return sub_type - 0x10
end
end
# check if factory 'safeboot' partition
def is_factory()
return self.type == 0 && self.subtype == 0
end
# check if the parition is a SPIFFS partition
# returns bool
def is_spiffs()
return self.type == 1 && self.subtype == 130
end
# get the actual image size give of the partition
# returns -1 if the partition is not an app ota partition
def get_image_size()
import flash
if self.is_ota() == nil && !self.is_factory() return -1 end
try
var addr = self.start
var magic_byte = flash.read(addr, 1).get(0, 1)
if magic_byte != 0xE9 return -1 end
var seg_count = flash.read(addr+1, 1).get(0, 1)
# print("Segment count", seg_count)
var seg_offset = addr + 0x20 # sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) = 24 + 8
var seg_num = 0
while seg_num < seg_count
# print(string.format("Reading 0x%08X", seg_offset))
var segment_header = flash.read(seg_offset - 8, 8)
var seg_start_addr = segment_header.get(0, 4)
var seg_size = segment_header.get(4,4)
# print(string.format("Segment %i: flash_offset=0x%08X start_addr=0x%08X size=0x%08X", seg_num, seg_offset, seg_start_addr, seg_size))
seg_offset += seg_size + 8 # add segment_length + sizeof(esp_image_segment_header_t)
seg_num += 1
end
var total_size = seg_offset - addr + 1 # add 1KB for safety
# print(string.format("Total size = %i KB", total_size/1024))
return total_size
except .. as e, m
tasmota.log("BRY: Exception> '" + e + "' - " + m, 2)
return -1
end
end
# Human readable version of Partition information
# this method is not included in the solidified version to save space,
# it is included only in the optional application `tapp` version
def tostring()
import string
var type_s = ""
var subtype_s = ""
if self.type == 0 type_s = "app"
if self.subtype == 0 subtype_s = "factory"
elif self.subtype >= 0x10 && self.subtype < 0x20 subtype_s = "ota" + str(self.subtype - 0x10)
elif self.subtype == 0x20 subtype_s = "test"
end
elif self.type == 1 type_s = "data"
if self.subtype == 0x00 subtype_s = "otadata"
elif self.subtype == 0x01 subtype_s = "phy"
elif self.subtype == 0x02 subtype_s = "nvs"
elif self.subtype == 0x03 subtype_s = "coredump"
elif self.subtype == 0x04 subtype_s = "nvskeys"
elif self.subtype == 0x05 subtype_s = "efuse_em"
elif self.subtype == 0x80 subtype_s = "esphttpd"
elif self.subtype == 0x81 subtype_s = "fat"
elif self.subtype == 0x82 subtype_s = "spiffs"
end
end
# reformat strings
if type_s != "" type_s = " (" + type_s + ")" end
if subtype_s != "" subtype_s = " (" + subtype_s + ")" end
return string.format("<instance: Partition_info(%d%s,%d%s,0x%08X,0x%08X,'%s',0x%X)>",
self.type, type_s,
self.subtype, subtype_s,
self.start, self.size,
self.label, self.flags)
end
def tobytes()
#- convert to raw bytes -#
var b = bytes('AA50') #- set magic number -#
b.resize(32).resize(2) #- pre-reserve 32 bytes -#
b.add(self.type, 1)
b.add(self.subtype, 1)
b.add(self.start, 4)
b.add(self.size, 4)
var label = bytes().fromstring(self.label)
label.resize(16)
b = b + label
b.add(self.flags, 4)
return b
end
end
partition_core.Partition_info = Partition_info
#-------------------------------------------------------------
- OTA Data
-
- Selection of the active OTA partition
-
typedef struct {
uint32_t ota_seq;
uint8_t seq_label[20];
uint32_t ota_state;
uint32_t crc; /* CRC32 of ota_seq field only */
} esp_ota_select_entry_t;
- Excerp from esp_ota_ops.c
esp32_idf use two sector for store information about which partition is running
it defined the two sector as ota data partition,two structure esp_ota_select_entry_t is saved in the two sector
named data in first sector as otadata[0], second sector data as otadata[1]
e.g.
if otadata[0].ota_seq == otadata[1].ota_seq == 0xFFFFFFFF,means ota info partition is in init status
so it will boot factory application(if there is),if there's no factory application,it will boot ota[0] application
if otadata[0].ota_seq != 0 and otadata[1].ota_seq != 0,it will choose a max seq ,and get value of max_seq%max_ota_app_number
and boot a subtype (mask 0x0F) value is (max_seq - 1)%max_ota_app_number,so if want switch to run ota[x],can use next formulas.
for example, if otadata[0].ota_seq = 4, otadata[1].ota_seq = 5, and there are 8 ota application,
current running is (5-1)%8 = 4,running ota[4],so if we want to switch to run ota[7],
we should add otadata[0].ota_seq (is 4) to 4 ,(8-1)%8=7,then it will boot ota[7]
if A=(B - C)%D
then B=(A + C)%D + D*n ,n= (0,1,2...)
so current ota app sub type id is x , dest bin subtype is y,total ota app count is n
seq will add (x + n*1 + 1 - seq)%n
-------------------------------------------------------------#
class Partition_otadata
var maxota #- number of highest OTA partition, default 1 (double ota0/ota1) -#
var offset #- offset of the otadata partition (0x2000 in length), default 0xE000 -#
var active_otadata #- which otadata block is active, 0 or 1, i.e. 0xE000 or 0xF000 -#
var seq0 #- ota_seq of first block -#
var seq1 #- ota_seq of second block -#
#- crc32 for ota_seq as 32 bits unsigned, with init vector -1 -#
static def crc32_ota_seq(seq)
import crc
return crc.crc32(0xFFFFFFFF, bytes().add(seq, 4))
end
#---------------------------------------------------------------------#
# Rest of the class
#---------------------------------------------------------------------#
def init(maxota, offset)
self.maxota = maxota
if self.maxota == nil self.maxota = 1 end
self.offset = offset
if self.offset == nil self.offset = 0xE000 end
self.active_otadata = 0
self.load()
end
#- update ota_max, needs to recompute everything -#
def set_ota_max(n)
self.maxota = n
end
# change the active OTA partition
def set_active(n)
var seq_max = 0 #- current highest seq number -#
var block_act = 0 #- block number containing the highest seq number -#
if self.seq0 != nil
seq_max = self.seq0
block_act = 0
end
if self.seq1 != nil && self.seq1 > seq_max
seq_max = self.seq1
block_act = 1
end
#- compute the next sequence number -#
var actual_ota = (seq_max - 1) % (self.maxota + 1)
if actual_ota != n #- change only if different -#
if n > actual_ota seq_max += n - actual_ota
else seq_max += (self.maxota + 1) - actual_ota + n
end
#- update internal structure -#
if block_act == 1 #- current block is 1, so update block 0 -#
self.seq0 = seq_max
else #- or write to block 1 -#
self.seq1 = seq_max
end
self._validate()
end
end
#- load otadata from SPI Flash -#
def load()
import flash
var otadata0 = flash.read(0xE000, 32)
var otadata1 = flash.read(0xF000, 32)
self.seq0 = otadata0.get(0, 4) #- ota_seq for block 1 -#
self.seq1 = otadata1.get(0, 4) #- ota_seq for block 2 -#
var valid0 = otadata0.get(28, 4) == self.crc32_ota_seq(self.seq0) #- is CRC32 valid? -#
var valid1 = otadata1.get(28, 4) == self.crc32_ota_seq(self.seq1) #- is CRC32 valid? -#
if !valid0 self.seq0 = nil end
if !valid1 self.seq1 = nil end
self._validate()
end
#- internally used, validate data -#
def _validate()
self.active_otadata = 0 #- if none is valid, default to OTA0 -#
if self.seq0 != nil
self.active_otadata = (self.seq0 - 1) % (self.maxota + 1)
end
if self.seq1 != nil && (self.seq0 == nil || self.seq1 > self.seq0)
self.active_otadata = (self.seq1 - 1) % (self.maxota + 1)
end
end
# Save partition information to SPI Flash
def save()
import flash
#- check the block number to save, 0 or 1. Choose the highest ota_seq -#
var block_to_save = -1 #- invalid -#
var seq_to_save = -1 #- invalid value -#
# check seq0
if self.seq0 != nil
seq_to_save = self.seq0
block_to_save = 0
end
if (self.seq1 != nil) && (self.seq1 > seq_to_save)
seq_to_save = self.seq1
block_to_save = 1
end
# if none was good
if block_to_save < 0 block_to_save = 0 end
if seq_to_save < 0 seq_to_save = 1 end
var offset_to_save = self.offset + 0x1000 * block_to_save #- default 0xE000 or 0xF000 -#
var bytes_to_save = bytes()
bytes_to_save.add(seq_to_save, 4)
bytes_to_save += bytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
bytes_to_save.add(self.crc32_ota_seq(seq_to_save), 4)
#- erase flash area and write -#
flash.erase(offset_to_save, 0x1000)
flash.write(offset_to_save, bytes_to_save)
end
# Produce a human-readable representation of the object with relevant information
def tostring()
import string
return string.format("<instance: Partition_otadata(ota_active:%d, ota_seq=[%d,%d], ota_max=%d)>",
self.active_otadata, self.seq0, self.seq1, self.maxota)
end
end
partition_core.Partition_otadata = Partition_otadata
#-------------------------------------------------------------
- Class for a partition table entry
-------------------------------------------------------------#
class Partition
var raw #- raw bytes of the partition table in flash -#
var md5 #- md5 hash of partition list -#
var slots
var otadata #- instance of Partition_otadata() -#
def init()
self.slots = []
self.load()
self.parse()
self.load_otadata()
end
# Load partition information from SPI Flash
def load()
import flash
self.raw = flash.read(0x8000,0x1000)
end
#- parse the raw bytes to a structured list of partition items -#
def parse()
for i:0..94 # there are maximum 95 slots + md5 (0xC00)
var item_raw = self.raw[i*32..(i+1)*32-1]
var magic = item_raw.get(0,2)
if magic == 0x50AA #- partition entry -#
var slot = partition_core.Partition_info(item_raw)
self.slots.push(slot)
elif magic == 0xEBEB #- MD5 -#
self.md5 = self.raw[i*32+16..i*33-1]
break
else
break
end
end
end
def get_ota_slot(n)
for slot: self.slots
if slot.is_ota() == n return slot end
end
return nil
end
#- compute the highest ota<x> partition -#
def ota_max()
var ota_max = 0
for slot:self.slots
if slot.type == 0 && (slot.subtype >= 0x10 && slot.subtype < 0x20)
var ota_num = slot.subtype - 0x10
if ota_num > ota_max ota_max = ota_num end
end
end
return ota_max
end
def load_otadata()
#- look for otadata partition offset, and max_ota -#
var otadata_offset = 0xE000 #- default value -#
var ota_max = self.ota_max()
for slot:self.slots
if slot.type == 1 && slot.subtype == 0 #- otadata -#
otadata_offset = slot.start
end
end
self.otadata = partition_core.Partition_otadata(ota_max, otadata_offset)
end
# get the active OTA app partition number
def get_active()
return self.otadata.active_otadata
end
#- change the active partition -#
def set_active(n)
if n < 0 || n > self.ota_max() raise "value_error", "Invalid ota partition number" end
self.otadata.set_ota_max(self.ota_max()) #- update ota_max if it changed -#
self.otadata.set_active(n)
end
# Human readable version of Partition information
# this method is not included in the solidified version to save space,
# it is included only in the optional application `tapp` version
#- convert to human readble -#
def tostring()
var ret = "<instance: Partition([\n"
for slot: self.slots
ret += " "
ret += slot.tostring()
ret += "\n"
end
ret += "],\n "
ret += self.otadata.tostring()
ret += "\n)>"
return ret
end
#- convert the slots to raw bytes, ready to falsh to parition page -#
def tobytes()
if size(self.slots) > 95 raise "value_error", "Too many partiition slots" end
var b = bytes()
for slot: self.slots
b += slot.tobytes()
end
#- compute MD5 -#
var md5 = MD5()
md5.update(b)
#- add the last segment -#
b += bytes("EBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
b += md5.finish()
#- complete -#
return b
end
#- write back to flash -#
def save()
import flash
var b = self.tobytes()
#- erase flash area and write -#
flash.erase(0x8000, 0x1000)
flash.write(0x8000, b)
self.otadata.save()
end
#- invalidate SPIFFS partition to force format at next boot -#
#- we simply erase the first byte of the first 2 blocks in the SPIFFS partition -#
def invalidate_spiffs()
import flash
#- we expect the SPIFFS partition to be the last one -#
var spiffs = self.slots[-1]
if !spiffs.is_spiffs() raise 'value_error', 'No SPIFFS partition found' end
var b = bytes("00") #- flash memory: we can turn bits from '1' to '0' -#
flash.write(spiffs.start , b) #- block #0 -#
flash.write(spiffs.start + 0x1000, b) #- block #1 -#
end
# switch to safeboot `factory` partition
def switch_factory()
import flash
flash.rollback()
end
end
partition_core.Partition = Partition
# init method to force the global `partition_core` is defined even if the import is done within a function
def init(m)
import global
global.partition_core = m
return m
end
partition_core.init = init
return partition_core
#- Example
import partition_core
# read
p = partition_core.Partition()
print(p)
-#

View File

@ -1,20 +0,0 @@
import os
import shutil
from os.path import join
from SCons.Script import DefaultEnvironment
env = DefaultEnvironment()
platform = env.PioPlatform()
FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32")
safemode_dir = join(env["PROJECT_DIR"], "safemode")
variants_dir = join(FRAMEWORK_DIR, "variants", "tasmota")
if env["PIOPLATFORM"] == "espressif32":
if os.path.exists(safemode_dir):
# print("safemode.bin dir exists")
if os.path.exists(variants_dir):
# print("variants/tasmota exists")
shutil.rmtree(variants_dir)
shutil.copytree(safemode_dir, variants_dir)

View File

@ -18,25 +18,78 @@
Import("env")
env = DefaultEnvironment()
platform = env.PioPlatform()
from genericpath import exists
import os
import sys
from os.path import join
import csv
import requests
import shutil
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
import esptool
FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32")
variants_dir = join(FRAMEWORK_DIR, "variants", "tasmota")
def esp32_fetch_safemode_bin(chip):
safemode_fw_url = "https://github.com/arendst/Tasmota-firmware/raw/main/firmware/tasmota32/tasmota" + chip[3:] + "-safemode.bin"
safemode_fw_name = join(variants_dir,"tasmota" + chip[3:] + "-safemode.bin")
if(exists(safemode_fw_name)):
print("Safemode binary already in place.")
return
print("Will download safemode binary from URL:")
print(safemode_fw_url)
response = requests.get(safemode_fw_url)
open(safemode_fw_name, "wb").write(response.content)
print("Safemode binary written to variants dir.")
def esp32_copy_new_safemode_bin(chip,new_local_safemode_fw):
print("Copy new local safemode firmware to variants dir -> using it for further flashing operations")
safemode_fw_name = join(variants_dir,"tasmota" + chip[3:] + "-safemode.bin")
if os.path.exists(variants_dir):
shutil.copy(new_local_safemode_fw, safemode_fw_name)
def esp32_create_combined_bin(source, target, env):
#print("Generating combined binary for serial flashing")
# The offset from begin of the file where the app0 partition starts
# This is defined in the partition .csv file
app_offset = 0x10000
factory_offset = -1 # error code value
app_offset = 0x10000 # default value for "old" scheme
spiffs_offset = -1 # error code value
with open(env.BoardConfig().get("build.partitions")) as csv_file:
print("Read partitions from ",env.BoardConfig().get("build.partitions"))
csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 0
for row in csv_reader:
if line_count == 0:
print(f'{", ".join(row)}')
line_count += 1
else:
print(f'{row[0]} {row[1]} {row[2]} {row[3]} {row[4]}')
line_count += 1
if(row[0] == 'app0'):
app_offset = int(row[3],base=16)
# elif(row[0] == 'factory'):
# factory_offset = int(row[3],base=16)
# elif(row[0] == 'spiffs'):
# spiffs_offset = int(row[3],base=16)
new_file_name = env.subst("$BUILD_DIR/${PROGNAME}.factory.bin")
sections = env.subst(env.get("FLASH_EXTRA_IMAGES"))
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
chip = env.get("BOARD_MCU")
if not os.path.exists(variants_dir):
os.makedirs(variants_dir)
if("safemode" in firmware_name):
esp32_copy_new_safemode_bin(chip,firmware_name)
else:
esp32_fetch_safemode_bin(chip)
flash_size = env.BoardConfig().get("upload.flash_size")
cmd = [
"--chip",
@ -54,8 +107,12 @@ def esp32_create_combined_bin(source, target, env):
print(f" - {sect_adr} | {sect_file}")
cmd += [sect_adr, sect_file]
print(f" - {hex(app_offset)} | {firmware_name}")
cmd += [hex(app_offset), firmware_name]
# "main" firmware to app0 - mandatory, except we just built a new safemode bin locally
if("safemode" not in firmware_name):
print(f" - {hex(app_offset)} | {firmware_name}")
cmd += [hex(app_offset), firmware_name]
else:
print("Upload new safemode binary only")
#print('Using esptool.py arguments: %s' % ' '.join(cmd))

View File

@ -34,7 +34,6 @@ build_flags = ${esp_defaults.build_flags}
-Wl,--wrap=panicHandler -Wl,--wrap=xt_unhandled_exception
-Wl,--wrap=_Z11analogWritehi ; `analogWrite(unsigned char, int)` use the Tasmota version of analogWrite for deeper integration and phase control
extra_scripts = pre:pio-tools/add_c_flags.py
pre:pio-tools/copy_safemode.py
post:pio-tools/post_esp32.py
${esp_defaults.extra_scripts}

View File

@ -116,6 +116,54 @@ lib_ignore =
Micro-RTSP
epdiy
[env:tasmota32-safemode]
extends = env:tasmota32_base
board = esp32_4M_2APP
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEMODE
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
TTGO TWatch Library
NimBLE-Arduino
Micro-RTSP
epdiy
[env:tasmota32s2-safemode]
extends = env:tasmota32_base
board = esp32s2_2APP
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEMODE
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
TTGO TWatch Library
NimBLE-Arduino
Micro-RTSP
epdiy
[env:tasmota32s3-safemode]
extends = env:tasmota32_base
board = esp32s3_2APP
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEMODE
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
TTGO TWatch Library
NimBLE-Arduino
Micro-RTSP
epdiy
[env:tasmota32c3-safemode]
extends = env:tasmota32_base
board = esp32c3_2APP
build_unflags = ${env:tasmota32_base.build_unflags}
-flto
-mtarget-align
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEMODE
-fno-lto
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
TTGO TWatch Library
NimBLE-Arduino
Micro-RTSP
epdiy
[env:tasmota32-AF]
extends = env:tasmota32_base
build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=af_AF -DFIRMWARE_TASMOTA32

Binary file not shown.

View File

@ -73,6 +73,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "ETH_PHY_POWER", (int32_t) GPIO_ETH_PHY_POWER },
{ "EXS_ENABLE", (int32_t) GPIO_EXS_ENABLE },
{ "FALLING", FALLING },
{ "FLOWRATEMETER_SIGNAL", (int32_t) GPIO_FLOWRATEMETER_IN },
{ "FTC532", (int32_t) GPIO_FTC532 },
{ "GPS_RX", (int32_t) GPIO_GPS_RX },
{ "GPS_TX", (int32_t) GPIO_GPS_TX },
@ -147,6 +148,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "MIEL_HVAC_RX", (int32_t) GPIO_MIEL_HVAC_RX },
{ "MIEL_HVAC_TX", (int32_t) GPIO_MIEL_HVAC_TX },
{ "MP3_DFR562", (int32_t) GPIO_MP3_DFR562 },
{ "MS01", (int32_t) GPIO_MS01 },
{ "NEOPOOL_RX", (int32_t) GPIO_NEOPOOL_RX },
{ "NEOPOOL_TX", (int32_t) GPIO_NEOPOOL_TX },
{ "NONE", (int32_t) GPIO_NONE },
@ -200,6 +202,12 @@ const be_const_member_t lv_gpio_constants[] = {
{ "SBR_RX", (int32_t) GPIO_SBR_RX },
{ "SBR_TX", (int32_t) GPIO_SBR_TX },
{ "SDCARD_CS", (int32_t) GPIO_SDCARD_CS },
{ "SDIO_CLK", (int32_t) GPIO_SDIO_CLK },
{ "SDIO_CMD", (int32_t) GPIO_SDIO_CMD },
{ "SDIO_D0", (int32_t) GPIO_SDIO_D0 },
{ "SDIO_D1", (int32_t) GPIO_SDIO_D1 },
{ "SDIO_D2", (int32_t) GPIO_SDIO_D2 },
{ "SDIO_D3", (int32_t) GPIO_SDIO_D3 },
{ "SDM120_RX", (int32_t) GPIO_SDM120_RX },
{ "SDM120_TX", (int32_t) GPIO_SDM120_TX },
{ "SDM230_RX", (int32_t) GPIO_SDM230_RX },

View File

@ -22,154 +22,27 @@ var partition = module('partition')
# } esp_partition_info_t_simplified;
#
#######################################################################
class Partition_info
var type
var subtype
var start
var size
var label
var flags
#- remove trailing NULL chars from a buffer before converting to string -#
#- Berry strings can contain NULL, but this messes up C-Berry interface -#
static def remove_trailing_zeroes(b)
while size(b) > 0
if b[-1] == 0 b.resize(size(b)-1)
else break end
end
return b
end
#
def init(raw)
if raw == nil || !issubclass(bytes, raw) # no payload, empty partition information
self.type = 0
self.subtype = 0
self.start = 0
self.size = 0
self.label = ''
self.flags = 0
return
end
#- we have a payload, parse it -#
var magic = raw.get(0,2)
if magic == 0x50AA #- partition entry -#
self.type = raw.get(2,1)
self.subtype = raw.get(3,1)
self.start = raw.get(4,4)
self.size = raw.get(8,4)
self.label = self.remove_trailing_zeroes(raw[12..27]).asstring()
self.flags = raw.get(28,4)
elif magic == 0xEBEB #- MD5 -#
else
import string
raise "internal_error", string.format("invalid magic number %02X", magic)
end
end
# check if the parition is an OTA partition
# if yes, return OTA number (starting at 0)
# if no, return nil
def is_ota()
if self.type == 0 && (self.subtype >= 0x10 && self.subtype < 0x20)
return self.subtype - 0x10
end
end
# check if the parition is a SPIFFS partition
# returns bool
def is_spiffs()
return self.type == 1 && self.subtype == 130
end
# get the actual image size give of the partition
# returns -1 if the partition is not an app ota partition
def get_image_size()
import flash
if self.is_ota() == nil return -1 end
try
var addr = self.start
var magic_byte = flash.read(addr, 1).get(0, 1)
if magic_byte != 0xE9 return -1 end
var seg_count = flash.read(addr+1, 1).get(0, 1)
# print("Segment count", seg_count)
var seg_offset = addr + 0x20 # sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) = 24 + 8
for seg_num:0..seg_count-1
# print(string.format("Reading 0x%08X", seg_offset))
var segment_header = flash.read(seg_offset - 8, 8)
var seg_start_addr = segment_header.get(0, 4)
var seg_size = segment_header.get(4,4)
# print(string.format("Segment %i: flash_offset=0x%08X start_addr=0x%08X size=0x%08X", seg_num, seg_offset, seg_start_addr, seg_size))
seg_offset += seg_size + 8 # add segment_length + sizeof(esp_image_segment_header_t)
end
var total_size = seg_offset - addr + 1 # add 1KB for safety
# print(string.format("Total size = %i KB", total_size/1024))
return total_size
except .. as e, m
print("BRY: Exception> '" + e + "' - " + m)
return -1
end
end
def tostring()
import string
var type_s = ""
var subtype_s = ""
if self.type == 0 type_s = "app"
if self.subtype == 0 subtype_s = "factory"
elif self.subtype >= 0x10 && self.subtype < 0x20 subtype_s = "ota" + str(self.subtype - 0x10)
elif self.subtype == 0x20 subtype_s = "test"
end
elif self.type == 1 type_s = "data"
if self.subtype == 0x00 subtype_s = "otadata"
elif self.subtype == 0x01 subtype_s = "phy"
elif self.subtype == 0x02 subtype_s = "nvs"
elif self.subtype == 0x03 subtype_s = "coredump"
elif self.subtype == 0x04 subtype_s = "nvskeys"
elif self.subtype == 0x05 subtype_s = "efuse_em"
elif self.subtype == 0x80 subtype_s = "esphttpd"
elif self.subtype == 0x81 subtype_s = "fat"
elif self.subtype == 0x82 subtype_s = "spiffs"
end
end
#- reformat strings -#
if type_s != "" type_s = " (" + type_s + ")" end
if subtype_s != "" subtype_s = " (" + subtype_s + ")" end
return string.format("<instance: Partition_info(%d%s,%d%s,0x%08X,0x%08X,'%s',0x%X)>",
self.type, type_s,
self.subtype, subtype_s,
self.start, self.size,
self.label, self.flags)
end
def tobytes()
#- convert to raw bytes -#
var b = bytes('AA50') #- set magic number -#
b.resize(32).resize(2) #- pre-reserve 32 bytes -#
b.add(self.type, 1)
b.add(self.subtype, 1)
b.add(self.start, 4)
b.add(self.size, 4)
var label = bytes().fromstring(self.label)
label.resize(16)
b = b + label
b.add(self.flags, 4)
return b
end
end
partition.Partition_info = Partition_info
# class Partition_info
#
# def init(raw)
#
# # check if the parition is an OTA partition
# # if yes, return OTA number (starting at 0)
# # if no, return nil
# def is_ota()
#
# # # check if the parition is a SPIFFS partition
# # returns bool
# def is_spiffs()
#
# # get the actual image size give of the partition
# # returns -1 if the partition is not an app ota partition
# def get_image_size()
#
# def tostring()
#
# def tobytes()
#end
#-------------------------------------------------------------
- OTA Data
@ -200,302 +73,77 @@ partition.Partition_info = Partition_info
so current ota app sub type id is x , dest bin subtype is y,total ota app count is n
seq will add (x + n*1 + 1 - seq)%n
-------------------------------------------------------------#
class Partition_otadata
var maxota #- number of highest OTA partition, default 1 (double ota0/ota1) -#
var offset #- offset of the otadata partition (0x2000 in length), default 0xE000 -#
var active_otadata #- which otadata block is active, 0 or 1, i.e. 0xE000 or 0xF000 -#
var seq0 #- ota_seq of first block -#
var seq1 #- ota_seq of second block -#
#-------------------------------------------------------------
- Simple CRC32 imple
-
- adapted from Python https://rosettacode.org/wiki/CRC-32#Python
-------------------------------------------------------------#
static def crc32_create_table()
var a = []
for i:0..255
var k = i
for j:0..7
if k & 1
k = (k >> 1) & 0x7FFFFFFF
k ^= 0xedb88320
else
k = (k >> 1) & 0x7FFFFFFF
end
end
a.push(k)
end
return a
end
static crc32_table = Partition_otadata.crc32_create_table()
static def crc32_update(buf, crc)
crc ^= 0xffffffff
for k:0..size(buf)-1
crc = (crc >> 8 & 0x00FFFFFF) ^ Partition_otadata.crc32_table[(crc & 0xff) ^ buf[k]]
end
return crc ^ 0xffffffff
end
#- crc32 for ota_seq as 32 bits unsigned, with init vector -1 -#
static def crc32_ota_seq(seq)
return Partition_otadata.crc32_update(bytes().add(seq, 4), 0xFFFFFFFF)
end
#---------------------------------------------------------------------#
# Rest of the class
#---------------------------------------------------------------------#
def init(maxota, offset)
self.maxota = maxota
if self.maxota == nil self.maxota = 1 end
self.offset = offset
if self.offset == nil self.offset = 0xE000 end
self.active_otadata = 0
self.load()
end
#- update ota_max, needs to recompute everything -#
def set_ota_max(n)
self.maxota = n
end
# change the active OTA partition
def set_active(n)
var seq_max = 0 #- current highest seq number -#
var block_act = 0 #- block number containing the highest seq number -#
if self.seq0 != nil
seq_max = self.seq0
block_act = 0
end
if self.seq1 != nil && self.seq1 > seq_max
seq_max = self.seq1
block_act = 1
end
#- compute the next sequence number -#
var actual_ota = (seq_max - 1) % (self.maxota + 1)
if actual_ota != n #- change only if different -#
if n > actual_ota seq_max += n - actual_ota
else seq_max += (self.maxota + 1) - actual_ota + n
end
#- update internal structure -#
if block_act == 1 #- current block is 1, so update block 0 -#
self.seq0 = seq_max
else #- or write to block 1 -#
self.seq1 = seq_max
end
self._validate()
end
end
#- load otadata from SPI Flash -#
def load()
import flash
var otadata0 = flash.read(0xE000, 32)
var otadata1 = flash.read(0xF000, 32)
self.seq0 = otadata0.get(0, 4) #- ota_seq for block 1 -#
self.seq1 = otadata1.get(0, 4) #- ota_seq for block 2 -#
var valid0 = otadata0.get(28, 4) == self.crc32_ota_seq(self.seq0) #- is CRC32 valid? -#
var valid1 = otadata1.get(28, 4) == self.crc32_ota_seq(self.seq1) #- is CRC32 valid? -#
if !valid0 self.seq0 = nil end
if !valid1 self.seq1 = nil end
self._validate()
end
#- internally used, validate data -#
def _validate()
self.active_otadata = 0 #- if none is valid, default to OTA0 -#
if self.seq0 != nil
self.active_otadata = (self.seq0 - 1) % (self.maxota + 1)
end
if self.seq1 != nil && (self.seq0 == nil || self.seq1 > self.seq0)
self.active_otadata = (self.seq1 - 1) % (self.maxota + 1)
end
end
# Save partition information to SPI Flash
def save()
import flash
#- check the block number to save, 0 or 1. Choose the highest ota_seq -#
var block_to_save = -1 #- invalid -#
var seq_to_save = -1 #- invalid value -#
# check seq0
if self.seq0 != nil
seq_to_save = self.seq0
block_to_save = 0
end
if (self.seq1 != nil) && (self.seq1 > seq_to_save)
seq_to_save = self.seq1
block_to_save = 1
end
# if none was good
if block_to_save < 0 block_to_save = 0 end
if seq_to_save < 0 seq_to_save = 1 end
var offset_to_save = self.offset + 0x1000 * block_to_save #- default 0xE000 or 0xF000 -#
var bytes_to_save = bytes()
bytes_to_save.add(seq_to_save, 4)
bytes_to_save += bytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
bytes_to_save.add(self.crc32_ota_seq(seq_to_save), 4)
#- erase flash area and write -#
flash.erase(offset_to_save, 0x1000)
flash.write(offset_to_save, bytes_to_save)
end
# Produce a human-readable representation of the object with relevant information
def tostring()
import string
return string.format("<instance: Partition_otadata(ota_active:%d, ota_seq=[%d,%d], ota_max=%d)>",
self.active_otadata, self.seq0, self.seq1, self.maxota)
end
end
partition.Partition_otadata = Partition_otadata
# class Partition_otadata
# var maxota #- number of highest OTA partition, default 1 (double ota0/ota1) -#
# var offset #- offset of the otadata partition (0x2000 in length), default 0xE000 -#
# var active_otadata #- which otadata block is active, 0 or 1, i.e. 0xE000 or 0xF000 -#
# var seq0 #- ota_seq of first block -#
# var seq1 #- ota_seq of second block -#
#
# #- crc32 for ota_seq as 32 bits unsigned, with init vector -1 -#
# static def crc32_ota_seq(seq)
#
# #---------------------------------------------------------------------#
# # Rest of the class
# #---------------------------------------------------------------------#
# def init(maxota, offset)
#
# #- update ota_max, needs to recompute everything -#
# def set_ota_max(n)
#
# # change the active OTA partition
# def set_active(n)
#
# #- load otadata from SPI Flash -#
# def load()
#
# # Save partition information to SPI Flash
# def save()
#
# # Produce a human-readable representation of the object with relevant information
# def tostring()
#end
#-------------------------------------------------------------
- Class for a partition table entry
-------------------------------------------------------------#
class Partition
var raw #- raw bytes of the partition table in flash -#
var md5 #- md5 hash of partition list -#
var slots
var otadata #- instance of Partition_otadata() -#
def init()
self.slots = []
self.load()
self.parse()
self.load_otadata()
end
# Load partition information from SPI Flash
def load()
import flash
self.raw = flash.read(0x8000,0x1000)
end
#- parse the raw bytes to a structured list of partition items -#
def parse()
for i:0..94 # there are maximum 95 slots + md5 (0xC00)
var item_raw = self.raw[i*32..(i+1)*32-1]
var magic = item_raw.get(0,2)
if magic == 0x50AA #- partition entry -#
var slot = Partition_info(item_raw)
self.slots.push(slot)
elif magic == 0xEBEB #- MD5 -#
self.md5 = self.raw[i*32+16..i*33-1]
break
else
break
end
end
end
def get_ota_slot(n)
for slot: self.slots
if slot.is_ota() == n return slot end
end
return nil
end
#- compute the highest ota<x> partition -#
def ota_max()
var ota_max = 0
for slot:self.slots
if slot.type == 0 && (slot.subtype >= 0x10 && slot.subtype < 0x20)
var ota_num = slot.subtype - 0x10
if ota_num > ota_max ota_max = ota_num end
end
end
return ota_max
end
def load_otadata()
#- look for otadata partition offset, and max_ota -#
var otadata_offset = 0xE000 #- default value -#
var ota_max = self.ota_max()
for slot:self.slots
if slot.type == 1 && slot.subtype == 0 #- otadata -#
otadata_offset = slot.start
end
end
self.otadata = Partition_otadata(ota_max, otadata_offset)
end
# get the active OTA app partition number
def get_active()
return self.otadata.active_otadata
end
#- change the active partition -#
def set_active(n)
if n < 0 || n > self.ota_max() raise "value_error", "Invalid ota partition number" end
self.otadata.set_ota_max(self.ota_max()) #- update ota_max if it changed -#
self.otadata.set_active(n)
end
#- convert to human readble -#
def tostring()
var ret = "<instance: Partition([\n"
for slot: self.slots
ret += " "
ret += slot.tostring()
ret += "\n"
end
ret += "],\n "
ret += self.otadata.tostring()
ret += "\n)>"
return ret
end
#- convert the slots to raw bytes, ready to falsh to parition page -#
def tobytes()
if size(self.slots) > 95 raise "value_error", "Too many partiition slots" end
var b = bytes()
for slot: self.slots
b += slot.tobytes()
end
#- compute MD5 -#
var md5 = MD5()
md5.update(b)
#- add the last segment -#
b += bytes("EBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
b += md5.finish()
#- complete -#
return b
end
#- write back to flash -#
def save()
import flash
var b = self.tobytes()
#- erase flash area and write -#
flash.erase(0x8000, 0x1000)
flash.write(0x8000, b)
self.otadata.save()
end
#- invalidate SPIFFS partition to force format at next boot -#
#- we simply erase the first byte of the first 2 blocks in the SPIFFS partition -#
def invalidate_spiffs()
import flash
#- we expect the SPIFFS partition to be the last one -#
var spiffs = self.slots[-1]
if !spiffs.is_spiffs() raise 'value_error', 'No SPIFFS partition found' end
var b = bytes("00") #- flash memory: we can turn bits from '1' to '0' -#
flash.write(spiffs.start , b) #- block #0 -#
flash.write(spiffs.start + 0x1000, b) #- block #1 -#
end
end
partition.Partition = Partition
#class Partition
# var raw #- raw bytes of the partition table in flash -#
# var md5 #- md5 hash of partition list -#
# var slots
# var otadata #- instance of Partition_otadata() -#
#
# def init()
#
# # Load partition information from SPI Flash
# def load()
#
# def get_ota_slot(n)
#
# #- compute the highest ota<x> partition -#
# def ota_max()
#
# def load_otadata()
#
# # get the active OTA app partition number
# def get_active()
#
# #- change the active partition -#
# def set_active(n)
#
# #- convert to human readble -#
# def tostring()
#
# #- convert the slots to raw bytes, ready to falsh to parition page -#
# def tobytes()
#
# #- write back to flash -#
# def save()
#
# #- invalidate SPIFFS partition to force format at next boot -#
# #- we simply erase the first byte of the first 2 blocks in the SPIFFS partition -#
# def invalidate_spiffs()
#end
#################################################################################
# Partition_manager_UI
@ -517,7 +165,7 @@ class Partition_manager_UI
#- ---------------------------------------------------------------------- -#
# Show a single OTA Partition
#- ---------------------------------------------------------------------- -#
def page_show_partition(slot, active, ota_num)
def page_show_partition(slot, active, ota_num, maxota)
import webserver
import string
#- define `bdis` style for gray disabled buttons -#
@ -535,21 +183,23 @@ class Partition_manager_UI
webserver.content_send("<p><b>Used</b>: unknown</p>")
webserver.content_send("<p><b>Free</b>: unknown</p>")
end
if !active && used > 0
webserver.content_send("<p><form id=setactive style='display: block;' action='/part_mgr' method='post' ")
webserver.content_send("onsubmit='return confirm(\"This will change the active partition and cause a restart.\");'>")
webserver.content_send("<button name='setactive' class='button bgrn'>Switch To This Partition</button>")
webserver.content_send(string.format("<input name='ota' type='hidden' value='%d'>", ota_num))
webserver.content_send("</form></p>")
else
# put a fake disabled button
webserver.content_send("<p><form style='display: block;'>")
if used >= 0
webserver.content_send("<button name='setactive' class='button bdis' disabled title=\"No need to click, it's already the active partition\">Current Active Partition</button>")
if maxota != nil && maxota > 0
if !active && used > 0
webserver.content_send("<p><form id=setactive style='display: block;' action='/part_mgr' method='post' ")
webserver.content_send("onsubmit='return confirm(\"This will change the active partition and cause a restart.\");'>")
webserver.content_send("<button name='setactive' class='button bgrn'>Switch To This Partition</button>")
webserver.content_send(string.format("<input name='ota' type='hidden' value='%d'>", ota_num))
webserver.content_send("</form></p>")
else
webserver.content_send("<button name='setactive' class='button bdis' disabled>Empty Partition</button>")
# put a fake disabled button
webserver.content_send("<p><form style='display: block;'>")
if used >= 0
webserver.content_send("<button name='setactive' class='button bdis' disabled title=\"No need to click, it's already the active partition\">Current Active Partition</button>")
else
webserver.content_send("<button name='setactive' class='button bdis' disabled>Empty Partition</button>")
end
webserver.content_send("</form></p>")
end
webserver.content_send("</form></p>")
end
webserver.content_send("<p></p></fieldset><p></p>")
@ -591,7 +241,9 @@ class Partition_manager_UI
var ota_num = slot.is_ota()
if ota_num != nil
# we have an OTA partition
self.page_show_partition(slot, ota_num == p.otadata.active_otadata, ota_num)
self.page_show_partition(slot, ota_num == p.otadata.active_otadata, ota_num, p.otadata.maxota)
elif slot.is_factory()
self.page_show_partition(slot, false, nil, nil)
elif slot.is_spiffs()
var flash_size = tasmota.memory()['flash'] * 1024
var used_size = (slot.start + slot.size)
@ -647,8 +299,9 @@ class Partition_manager_UI
def page_part_mgr()
import webserver
import string
import partition_core
if !webserver.check_privileged_access() return nil end
var p = partition.Partition()
var p = partition_core.Partition()
webserver.content_start("Partition Manager") #- title of the web page -#
webserver.content_send_style() #- send standard Tasmota styles -#
@ -659,9 +312,11 @@ class Partition_manager_UI
self.page_show_partitions(p)
webserver.content_send("<p></p></fieldset><p></p>")
webserver.content_send("<fieldset><legend><b>&nbsp;Re-partition</b></legend><p></p>")
self.page_show_repartition_asym(p)
webserver.content_send("<p></p></fieldset><p></p>")
if p.otadata.maxota > 0
webserver.content_send("<fieldset><legend><b>&nbsp;Re-partition</b></legend><p></p>")
self.page_show_repartition_asym(p)
webserver.content_send("<p></p></fieldset><p></p>")
end
webserver.content_button(webserver.BUTTON_MANAGEMENT) #- button back to management page -#
webserver.content_stop() #- end of web page -#
@ -673,10 +328,11 @@ class Partition_manager_UI
def page_part_ctl()
import webserver
import string
import partition_core
if !webserver.check_privileged_access() return nil end
#- check that the partition is valid -#
var p = partition.Partition()
var p = partition_core.Partition()
try
#---------------------------------------------------------------------#
@ -847,6 +503,7 @@ partition.Partition_manager_UI = Partition_manager_UI
#- create and register driver in Tasmota -#
if tasmota
import partition_core
var partition_manager_ui = partition.Partition_manager_UI()
tasmota.add_driver(partition_manager_ui)
## can be removed if put in 'autoexec.bat'

View File

@ -2,7 +2,7 @@
// compressed by tools/unishox/compress-html-uncompressed.py
/////////////////////////////////////////////////////////////////////
const size_t HTTP_HEAD_LAST_SCRIPT_SIZE = 355;
const size_t HTTP_HEAD_LAST_SCRIPT_SIZE = 346;
const char HTTP_HEAD_LAST_SCRIPT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x46\xB1\x0E\xE9\xDE\x3D\xA6\x77\xF5\x47\xC3\x8C\xEA\x2D\x3E"
"\x09\x81\x8B\x1A\xFA\x8E\x86\xA1\x6F\xE6\x45\xE6\x13\x0E\xB3\xE5\x61\x04\x77\x4F"
"\xBD\xE1\x82\xE8\xEA\x1C\x2E\xAB\x38\xEA\xA6\x6C\xAB\xFB\xB3\xAB\xCC\x26\x1D\x1F"
@ -13,7 +13,6 @@ const char HTTP_HEAD_LAST_SCRIPT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x4
"\x04\x1C\x87\x44\x3E\xCF\x7C\xF3\x04\x7C\xB0\xF0\x7B\xA8\xED\x9D\xB3\xC1\xEE\x3D"
"\xC0\x89\xC1\x77\x8C\x1D\xDF\x03\x02\xE0\xBC\xE8\x28\xC0\x2F\x70\x2C\x74\xF5\x19"
"\x04\xCE\x82\x6F\x86\x05\x66\x47\xCF\x1D\xA3\xEC\x70\x58\x19\xA1\xF6\x79\x9F\x7D"
"\x9C\xCF\xB0\x43\xD7\x47\xC2\x3B\xA6\xB1\x0E\xF1\xE0\xF4\x3B\x3C\x1F\xF4\x65\x1F"
"\x86";
"\x9C\xCF\xB0\x43\xD7\x47\xC2\x3B\xA6\xB1\x0E\xF1\xE0";
#define HTTP_HEAD_LAST_SCRIPT Decompress(HTTP_HEAD_LAST_SCRIPT_COMPRESSED,HTTP_HEAD_LAST_SCRIPT_SIZE).c_str()

View File

@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////
// compressed by tools/unishox/compress-html-uncompressed.py
/////////////////////////////////////////////////////////////////////
const size_t HTTP_HEAD_LAST_SCRIPT32_SIZE = 989;
const char HTTP_HEAD_LAST_SCRIPT32_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x46\xB1\x0E\xE9\xDE\x3D\xA6\x77\xF5\x47\xC3\x8C\xEA\x2D\x3E"
"\x09\x81\x8B\x1A\xFA\x8E\x86\xA1\x6F\xE6\x45\xE6\x13\x0E\xB3\xE5\x61\x04\x77\x4F"
"\xBD\xE1\x82\xE8\xEA\x1C\x2E\xAB\x38\xEA\xA6\x6C\xAB\xFB\xB3\xAB\xCC\x26\x1D\x1F"
"\x67\x78\xF0\x3E\x2B\x42\x67\x77\x4E\x81\x3E\x1E\xA1\x47\xE1\xF2\x8E\xF1\xED\xD3"
"\x07\x77\x4F\x7A\x8F\x7C\xEF\x1E\xDD\x3D\xEA\x3D\xF3\xDE\x3E\xFA\xC6\xB3\xEC\xF7"
"\xCF\x87\x77\x4F\x7A\x8F\x7C\xE8\x2A\x2B\xFC\x57\x55\xFD\x1C\x2E\x99\xDD\x3E\xF4"
"\x43\xEC\xEF\x1F\xA3\xF4\x77\x4F\xE0\x27\x57\xEB\x1A\xCF\xB3\xBC\x77\x8E\xF1\xDA"
"\x04\x1C\x87\x44\x3E\xCF\x7C\xF3\x04\x7C\xB0\xF0\x7B\xA8\xED\x9D\xB3\xC1\xEE\x3D"
"\xC0\x89\xC1\x77\x8C\x1D\xDF\x03\x02\xE0\xBC\xE8\x28\xC0\x2F\x70\x2C\x74\xF5\x19"
"\x04\xCE\x82\x6F\x86\x05\x66\x47\xCF\x1D\xA3\xEC\x70\x58\x19\xA1\xF6\x79\x9F\x7D"
"\x9C\xCF\xB0\x43\xD7\x47\xC2\x3B\xA6\xB1\x0E\xF1\xE0\x11\x76\x41\x67\x76\x8E\xF1"
"\xED\x63\x8E\xE9\xF6\x60\xE5\x9F\x67\x78\x81\x2B\x21\x04\x2C\x5D\x8E\x3B\xA7\xD9"
"\x83\x94\x40\x9B\x68\x10\x73\xD3\xC5\x1D\x0C\x67\xC6\x9D\x3C\x2C\x70\xDD\xA3\xBA"
"\x77\x8F\x2A\x01\x8B\xC2\x08\xB1\x81\x1D\xDA\x04\x1E\x10\xBC\x11\xF0\x10\x70\x43"
"\xDE\x3E\xC5\x9C\xA3\xEC\xF7\xCE\x84\x63\x42\x7E\x3D\xE3\x8C\xF7\xCE\x85\xE0\xB4"
"\x36\x77\x4E\x33\xAA\x1D\xE3\xC1\x19\xDF\xD7\xC4\x3E\x73\x1F\x44\x63\x42\x65\xF7"
"\x62\x3F\x9D\xD3\xBC\x78\xF8\x87\x4C\xE0\xB2\xC4\x3E\x1D\xD3\xBC\x7C\x3F\x0F\x69"
"\x9D\xFD\x0E\x1C\x7C\xE6\x3E\x88\x5E\xF5\x1C\xF9\x15\xFF\xF6\x64\x77\x7E\x21\xD3"
"\xEF\xC2\xC2\xA3\xBC\x78\xD3\x07\x74\x70\xE0\x42\xE2\x14\xF8\x7C\x39\x0F\xD1\xFA"
"\x21\xC3\x8F\x78\xE3\x3D\xF3\xE1\xF1\x91\xB0\x99\xC4\x77\x8F\x69\x18\x0E\x8E\xED"
"\x1D\xE3\xC1\xEE\x61\x79\x9E\xD0\x4C\xE0\x60\xF0\x7B\x8F\x1F\x10\xE9\xF7\x62\x15"
"\xF8\xAF\xFF\xB3\x22\x1C\x2C\xC1\x87\xF3\xBB\xE0\x8E\xF1\xE3\xEE\x85\xFF\x91\x8B"
"\x0B\xCC\xF0\x7B\x81\x17\x8A\x2A\x01\x41\xCB\x8F\x69\x9D\xFD\x1B\x0F\x9C\xC7\xD1"
"\x1B\x08\x69\x04\x42\xAA\x86\x17\xD9\xA8\x5B\xF5\x1D\xD3\xBC\x78\x36\x1D\x30\x63"
"\xE3\xBA\x7D\x90\xF1\x32\xA3\xEC\xEA\x3E\xCE\xC1\x67\x30\xED\x10\xB3\x98\x7C\x23"
"\x01\xD1\xFA\xB1\x9A\x7C\x3E\xCE\xAA\xF8\xB6\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65"
"\xEA\xBA\x61\x8A\xBE\x1E\x60\x83\xC2\x76\x98\x3B\xA6\xC3\xA7\xDD\x88\x64\x5E\xAB"
"\xA6\x7C\x3E\x1C\xC3\xF4\x7E\x88\xD8\x74\xF5\x5D\x0B\xF1\xF0\xF8\x72\x9B\x20\x42"
"\xE3\x2A\x01\xF8\x6C\x3A\x7D\xF8\x66\x77\x99\x53\x36\x51\xE3\x4C\x1D\xDF\x1F\x0F"
"\x87\xD9\x8B\x0B\xCC\xFB\x3B\xDE\x74\x55\xA3\x5E\x0B\xA3\xBA\x77\x4E\xF1\xF0\xFC"
"\x04\x4E\x19\x4E\xA3\x9C\xDB\x3B\xC4\x08\x78\x4D\x7C\x5B\x3E\xCE\xF7\x85\x82\x27"
"\x10\x08\x16\x75\xA3\x8C\xEF\x1E\xD2\x05\x4C\xD4\xE5\x36\xC8\x10\x78\xB0\x36\x1D"
"\x3C\xF8\x43\xBA\x77\x8F\x07\xB8\xF4\x3B\x3C\x1F\xF4\x65\x1F\x86";
#define HTTP_HEAD_LAST_SCRIPT32 Decompress(HTTP_HEAD_LAST_SCRIPT32_COMPRESSED,HTTP_HEAD_LAST_SCRIPT32_SIZE).c_str()

View File

@ -18,4 +18,4 @@ const char HTTP_HEAD_LAST_SCRIPT[] PROGMEM =
"}"
"}"
"wl(jd);" // Add name='' to any id='' in input,button,textarea,select
"</script>";
;

View File

@ -0,0 +1,65 @@
const char HTTP_HEAD_LAST_SCRIPT32[] PROGMEM =
"function jd(){" // Add label name='' based on provided id=''
"var t=0,i=document.querySelectorAll('input,button,textarea,select');"
"while(i.length>=t){"
"if(i[t]){"
"i[t]['name']=(i[t].hasAttribute('id')&&(!i[t].hasAttribute('name')))?i[t]['id']:i[t]['name'];"
"}"
"t++;"
"}"
"}"
"function sf(s){"
"var t=0,i=document.querySelectorAll('.hf');"
"while(i.length>=t){"
"if(i[t]){"
"i[t].style.display=s?'block':'none';"
"}"
"t++;"
"}"
"}"
"wl(jd);" // Add name='' to any id='' in input,button,textarea,select
// experimental
"function su(t){"
// "console.log('su()');"
"eb('f3').style.display='none';"
"eb('f2').style.display='block';"
"t.form.submit();"
"}"
"function upl(t){" // check file's first byte to decide next step
"var sl=t.form['u2'].files[0].slice(0,1);" // load only first byte of file
// "console.log(sl);"
// "console.log(sl.length);"
"var rd=new FileReader();"
"rd.onload=()=>{"
// "console.log(\"rd.onload\");"
"var bb=new Uint8Array(rd.result);"
// "console.log(bb[0]);"
// "console.log(bb.length);"
"if(bb.length==1&&bb[0]==0xE9){"
"fct(t);" // upload via factory
"}else{"
"t.form.submit();" // normal upload
"};"
"};"
"rd.readAsArrayBuffer(sl);"
"return false;"
"};"
"function fct(t){"
"var x=new XMLHttpRequest();"
"x.open('GET','/u4?u4=fct&api=',true);"
"x.onreadystatechange=()=>{"
// "console.log('x.readyState=%%i x.status=%%i',x.readyState,x.status);"
"if(x.readyState==4&&x.status==200){"
"var s=x.responseText;"
// "console.log('responseText:'+s);"
"if(s=='false')setTimeout(()=>{fct(t);},6000);"
"if(s=='true')su(t);"
"}else if(x.readyState==4&&x.status==0){"
"setTimeout(()=>{fct(t);},2000);" // retry in 2 seconds
"};"
"};"
"x.send();"
// "console.log('after send');"
"}"
"</script>";

View File

@ -372,6 +372,7 @@
#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_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Oplaai begin"
#define D_UPGRADE_STARTED "Opgradering is begin"
#define D_UPLOAD_DONE "Oplaai gedoen"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Wagwoord geverifieer" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Fout" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowmeter"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "Адрес на сървър за OTA"
#define D_START_UPGRADE "Начало на обновяване"
#define D_UPGRADE_BY_FILE_UPLOAD "Обновяване от файл"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Качване"
#define D_UPGRADE_STARTED "Обновяване"
#define D_UPLOAD_DONE "Качването завърши"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Грешка" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "URL OTA"
#define D_START_UPGRADE "Start aktualizace"
#define D_UPGRADE_BY_FILE_UPLOAD "Aktualizace nahráním souboru"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Nahrávání zahájeno"
#define D_UPGRADE_STARTED "Zahájení aktualizace"
#define D_UPLOAD_DONE "Nahrávání ukončeno"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA-URL"
#define D_START_UPGRADE "Update starten"
#define D_UPGRADE_BY_FILE_UPLOAD "Update Datei hochladen"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Upload gestartet"
#define D_UPGRADE_STARTED "Update gestartet"
#define D_UPLOAD_DONE "Upload abgeschlossen"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Neue Adresse"
#define D_OUT_OF_RANGE "Außerhalb Bereich"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Übereinstimmung" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Fehler" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Durchflussmesser"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA URL"
#define D_START_UPGRADE "Εκκίνηση αναβάθμισης"
#define D_UPGRADE_BY_FILE_UPLOAD "Αναβάθμιση με μεταφόρτωση αρχείου"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Η μεταφόρτωση ξεκίνησε"
#define D_UPGRADE_STARTED "Η αναβάθμιση ξεκίνησε"
#define D_UPLOAD_DONE "Η μεταφόρτωση ολοκληρώθηκε"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Start upgrade"
#define D_UPGRADE_BY_FILE_UPLOAD "Upgrade by file upload"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Upload started"
#define D_UPGRADE_STARTED "Upgrade started"
#define D_UPLOAD_DONE "Upload done"
@ -866,6 +867,7 @@
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Comenzar actualización"
#define D_UPGRADE_BY_FILE_UPLOAD "Actualizar cargando archivo bin"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Cargando archivo"
#define D_UPGRADE_STARTED "Actualización iniciada"
#define D_UPLOAD_DONE "Carga finalizada"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Cambiando dirección a"
#define D_OUT_OF_RANGE "Fuera de Rango"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Clave Correcta" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "URL OTA"
#define D_START_UPGRADE "Lancer la mise à jour"
#define D_UPGRADE_BY_FILE_UPLOAD "Mise à jour par téléchargement fichier"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Téléchargement lancé"
#define D_UPGRADE_STARTED "Mise à jour lancée"
#define D_UPLOAD_DONE "Téléchargement terminé"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Positionner l'adresse à"
#define D_OUT_OF_RANGE "Hors limites"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Mot-de-passe vérifié" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Erreur" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Begjin upgrade"
#define D_UPGRADE_BY_FILE_UPLOAD "Upgrade op bestân upload"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Upload begon"
#define D_UPGRADE_STARTED "Upgrade begon"
#define D_UPLOAD_DONE "Upload dien"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA כתובת"
#define D_START_UPGRADE "התחל בשדרוג"
#define D_UPGRADE_BY_FILE_UPLOAD "שדרוג דרך קובץ נכשל"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "העלאה מתחילה"
#define D_UPGRADE_STARTED "שדרוג מתחיל"
#define D_UPLOAD_DONE "העלאה הסתיימה"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA URL"
#define D_START_UPGRADE "Frissítés"
#define D_UPGRADE_BY_FILE_UPLOAD "Frissítés helyi fájllal"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Feltöltés elindítva"
#define D_UPGRADE_STARTED "Frissítés elindítva"
#define D_UPLOAD_DONE "Feltöltés kész"
@ -866,6 +867,7 @@
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Jelszó ellenőrizve" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Hiba" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -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 v11.0.0.7 - Last update 19.04.2022
* Updated until v9.4.0.1 - Last update 03.05.2022
\*********************************************************************/
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -372,6 +372,7 @@
#define D_OTA_URL "URL OTA"
#define D_START_UPGRADE "Esegui aggiornamento"
#define D_UPGRADE_BY_FILE_UPLOAD "Aggiornamento tramite file locale"
#define D_UPLOAD_FACTORY "Passaggio a partizione avvio sicuro"
#define D_UPLOAD_STARTED "Caricamento..."
#define D_UPGRADE_STARTED "Aggiornamento..."
#define D_UPLOAD_DONE "Caricamento completato"
@ -710,7 +711,7 @@
#define D_SENSOR_MAX31855_CLK "MX31855 - CLK"
#define D_SENSOR_MAX31855_DO "MX31855 - DO"
#define D_SENSOR_MAX31865_CS "MX31865 - CS"
#define D_SENSOR_NRG_SEL "HLWBL - SEL" // Suffix "i"
#define D_SENSOR_NRG_SEL "HLWBL - SEL" // Suffix "i"
#define D_SENSOR_NRG_CF1 "HLWBL - CF1"
#define D_SENSOR_HLW_CF "HLW8012 - CF"
#define D_SENSOR_HJL_CF "BL0937 - CF"
@ -735,7 +736,7 @@
#define D_SENSOR_ARIRFSEL "IR ALux - SEL"
#define D_SENSOR_TXD "Seriale - TX"
#define D_SENSOR_RXD "Seriale - RX"
#define D_SENSOR_ROTARY "Rotativo" // Suffix "1A"
#define D_SENSOR_ROTARY "Rotativo" // Suffix "1A"
#define D_SENSOR_HRE_CLOCK "HRE - Clock"
#define D_SENSOR_HRE_DATA "HRE - Dati"
#define D_SENSOR_ADE7880_IRQ "ADE7880 - IRQ"
@ -866,6 +867,7 @@
#define D_GPIO_SHIFT595_SER "74x595 - SER"
#define D_SENSOR_CM11_TX "CM110x - TX"
#define D_SENSOR_CM11_RX "CM110x - RX"
#define D_SENSOR_FLOWRATEMETER "Portata"
// Units
#define D_UNIT_AMPERE "A"
@ -913,24 +915,26 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/ora"
#define D_NEW_ADDRESS "Imposta indirizzo a"
#define D_OUT_OF_RANGE "Fuori intervallo"
#define D_SENSOR_DETECTED "rilevato"
//SDM220, SDM120, SDM72, LE01MR, SDM230
#define D_EXPORT_POWER "Potenza esportata"
#define D_IMPORT_POWER "Potenza importata"
#define D_PHASE_ANGLE "Angolo fase"
#define D_IMPORT_ACTIVE "Potenza attiva importata"
#define D_EXPORT_ACTIVE "Potenza attiva esportata"
#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_ANGLE "°"
#define D_TOTAL_ACTIVE "Potenza attiva totale"
#define D_RESETTABLE_TOTAL_ACTIVE "Potenza attiva totale (RST)"
#define D_EXPORT_POWER "Potenza esportata"
#define D_IMPORT_POWER "Potenza importata"
#define D_PHASE_ANGLE "Angolo fase"
#define D_IMPORT_ACTIVE "Potenza attiva importata"
#define D_EXPORT_ACTIVE "Potenza attiva esportata"
#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_ANGLE "°"
#define D_TOTAL_ACTIVE "Potenza attiva totale"
#define D_RESETTABLE_TOTAL_ACTIVE "Potenza attiva totale (RST)"
//SOLAXX1
#define D_PV1_VOLTAGE "PV1 - Voltaggio"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verificata" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Errore" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Portata"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "업그레이드 시작"
#define D_UPGRADE_BY_FILE_UPLOAD "파일에서 업로드해 업그레이드"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "업로드 시작됨"
#define D_UPGRADE_STARTED "업그레이드 시작됨"
#define D_UPLOAD_DONE "업그레이드 완료"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Start opwaarderen"
#define D_UPGRADE_BY_FILE_UPLOAD "Opwaarderen dmv verzenden bestand"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Verzending gestart"
#define D_UPGRADE_STARTED "Opwaarderen gestart"
#define D_UPLOAD_DONE "Opwaarderen klaar"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Nieuw adres"
#define D_OUT_OF_RANGE "Buiten beriek"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Wachtwoord herkend" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Fout" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "Adres serwera"
#define D_START_UPGRADE "Aktualizuj"
#define D_UPGRADE_BY_FILE_UPLOAD "Aktualizacja z pliku"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Wgrywanie rozpoczęte"
#define D_UPGRADE_STARTED "Aktualizacja rozpoczęta"
#define D_UPLOAD_DONE "Wgrywanie zakończone"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Ustawiam adres na"
#define D_OUT_OF_RANGE "Poza zakresem"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Zweryfikowano poprawnie" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Błąd" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA URL"
#define D_START_UPGRADE "Iniciar atualização"
#define D_UPGRADE_BY_FILE_UPLOAD "Atualização por arquivo local"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Início do envio"
#define D_UPGRADE_STARTED "Atualização iniciada"
#define D_UPLOAD_DONE "Atualização finalizada"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "W/h"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Mudança de endereço para"
#define D_OUT_OF_RANGE "Fora de Alcance"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Senha verificada" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Erro" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "Url OTA"
#define D_START_UPGRADE "Iniciar atualização"
#define D_UPGRADE_BY_FILE_UPLOAD "Atualizar por envio de ficheiro"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Envio Iniciado"
#define D_UPGRADE_STARTED "Atualização Iniciada"
#define D_UPLOAD_DONE "Atualização Finalizada"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Mudança de endereço para"
#define D_OUT_OF_RANGE "Fora de Alcance"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Porneste actualizare"
#define D_UPGRADE_BY_FILE_UPLOAD "Actualizare prin încărcare fișier"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Încărcare începută"
#define D_UPGRADE_STARTED "Actualizare începută"
#define D_UPLOAD_DONE "Încărcare terminată"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Начать обновление"
#define D_UPGRADE_BY_FILE_UPLOAD "Обновление путем загрузки файлов"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Загрузка началась"
#define D_UPGRADE_STARTED "Обновление началось"
#define D_UPLOAD_DONE "Загрузка завершена"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "А"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "Вт"
#define D_UNIT_WATTHOUR "ВтЧ"
#define D_UNIT_WATT_METER_QUADRAT "Вт/м²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "URL OTA"
#define D_START_UPGRADE "Spustiť aktualizáciu"
#define D_UPGRADE_BY_FILE_UPLOAD "Aktualizácia nahraním súboru"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Nahrávanie spustené"
#define D_UPGRADE_STARTED "Aktualizácia spustená"
#define D_UPLOAD_DONE "Nahrávanie ukončené"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Starta uppdatering"
#define D_UPGRADE_BY_FILE_UPLOAD "Uppgradering via filuppladdning"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Uppladdning startad"
#define D_UPGRADE_STARTED "Uppgradeing startad"
#define D_UPLOAD_DONE "Uppladdning klar"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Yükseltmeyi başlat"
#define D_UPGRADE_BY_FILE_UPLOAD "Dosya kullanrak yükset"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Yükleme başlatıldı"
#define D_UPGRADE_STARTED "YÜkestlme başlatıldı"
#define D_UPLOAD_DONE "Yükleme Tamamlandı"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA URL"
#define D_START_UPGRADE "Почати оновлення"
#define D_UPGRADE_BY_FILE_UPLOAD "Оновлення шляхом завантаження файлів"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Завантаження почалось"
#define D_UPGRADE_STARTED "Оновлення почалось"
#define D_UPLOAD_DONE "Завантаження завершено"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "А"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "Вт"
#define D_UNIT_WATTHOUR "Вт/г"
#define D_UNIT_WATT_METER_QUADRAT "Вт/м²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "Đường dẫn OTA"
#define D_START_UPGRADE "Bắt đầu nâng cấp"
#define D_UPGRADE_BY_FILE_UPLOAD "Nâng cấp thông qua tải lên tệp"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "Bắt đầu tải lên"
#define D_UPGRADE_STARTED "Bắt đầu nâng cấp"
#define D_UPLOAD_DONE "Hoàn thành tải tệp"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA 地址"
#define D_START_UPGRADE "开始升级"
#define D_UPGRADE_BY_FILE_UPLOAD "通过文件升级"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "开始上传"
#define D_UPGRADE_STARTED "开始升级"
#define D_UPLOAD_DONE "上传完成"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "A"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -372,6 +372,7 @@
#define D_OTA_URL "OTA網址"
#define D_START_UPGRADE "開始升級"
#define D_UPGRADE_BY_FILE_UPLOAD "透過檔案升級"
#define D_UPLOAD_FACTORY "Switching to safeboot partition"
#define D_UPLOAD_STARTED "已開始上傳"
#define D_UPGRADE_STARTED "已開始升級"
#define D_UPLOAD_DONE "已上傳完成"
@ -865,7 +866,8 @@
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
// Units
#define D_UNIT_AMPERE "安培"
@ -913,6 +915,8 @@
#define D_UNIT_WATT "瓦特"
#define D_UNIT_WATTHOUR "瓦小時"
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@ -1054,6 +1058,9 @@
#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed
#define D_FP_UNKNOWNERROR "Error" // Any other error
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife"

View File

@ -948,6 +948,8 @@
//#define USE_NEOPOOL // Add support for Sugar Valley NeoPool Controller - also known under brands Hidrolife, Aquascenic, Oxilife, Bionet, Hidroniser, UVScenic, Station, Brilix, Bayrol and Hay (+6k flash, +60 mem)
// #define NEOPOOL_MODBUS_ADDRESS 1 // Any modbus address
//#define FLOWRATEMETER // Add support for water flow meter YF-DN50 and similary (+1k7 code)
// -- Thermostat control ----------------------------
//#define USE_THERMOSTAT // Add support for Thermostat
#define THERMOSTAT_CONTROLLER_OUTPUTS 1 // Number of outputs to be controlled independently

View File

@ -366,7 +366,7 @@ typedef union {
uint8_t data;
struct {
uint8_t spare0 : 1;
uint8_t spare1 : 1;
uint8_t flowratemeter_unit : 1; // Sensor96 9,x - unit l/min (0) or m³/h (1)
uint8_t bh1750_2_resolution : 2;
uint8_t bh1750_1_resolution : 2; // Sensor10 1,2,3
uint8_t hx711_json_weight_change : 1; // Sensor34 8,x - Enable JSON message on weight change
@ -794,10 +794,10 @@ typedef struct {
uint8_t tcp_config; // F5F
uint8_t light_step_pixels; // F60
uint8_t free_f61[27]; // F61 - Decrement if adding new Setting variables just above and below
uint8_t free_f61[23]; // F61 - Decrement if adding new Setting variables just above and below
// Only 32 bit boundary variables below
uint16_t flowratemeter_calibration[2];// F78
int32_t energy_kWhexport_ph[3]; // F7C
uint32_t eth_ipv4_address[5]; // F88
uint32_t energy_kWhtotal; // F9C

View File

@ -295,14 +295,37 @@ extern "C" {
#include "rom/spi_flash.h"
#endif
bool EspSingleOtaPartition(void) {
return (1 == esp_ota_get_app_partition_count());
}
bool EspRunningFactoryPartition(void) {
const esp_partition_t *cur_part = esp_ota_get_running_partition();
return (cur_part->type == 0 && cur_part->subtype == 0);
}
void EspPrepRestartToSafeMode(void) {
// esp_ota_mark_app_invalid_rollback_and_reboot(); // Doesn't work 20220501
const esp_partition_t *otadata_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
if (otadata_partition) {
esp_partition_erase_range(otadata_partition, 0, SPI_FLASH_SEC_SIZE * 2);
}
}
uint32_t EspFlashBaseAddress(void) {
const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr);
if (!partition) { return 0; }
return partition->address; // For tasmota 0x00010000 or 0x00200000
if (EspSingleOtaPartition()) { // Only one partition so start at end of sketch
const esp_partition_t *running = esp_ota_get_running_partition();
if (!running) { return 0; }
return running->address + ESP_getSketchSize();
} else { // Select other partition
const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr);
if (!partition) { return 0; }
return partition->address; // For tasmota 0x00010000 or 0x00200000
}
}
uint32_t EspFlashBaseEndAddress(void) {
const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr);
const esp_partition_t* partition = (EspSingleOtaPartition()) ? esp_ota_get_running_partition() : esp_ota_get_next_update_partition(nullptr);
if (!partition) { return 0; }
return partition->address + partition->size; // For tasmota 0x00200000 or 0x003F0000
}
@ -664,7 +687,7 @@ typedef struct {
if (rev3) { return F("ESP32-PICO-V3"); } // Max 240MHz, Dual core, LGA 7*7, ESP32-PICO-V3-ZERO, ESP32-PICO-V3-ZERO-DevKit
else { return F("ESP32-PICO-D4"); } // Max 240MHz, Dual core, LGA 7*7, 4MB embedded flash, ESP32-PICO-KIT
case 6: return F("ESP32-PICO-V3-02"); // Max 240MHz, Dual core, LGA 7*7, 8MB embedded flash, 2MB embedded PSRAM, ESP32-PICO-MINI-02, ESP32-PICO-DevKitM-2
case 7: return F("ESP32-D0WDR2-V3"); // Max 240MHz, Dual core, QFN 5*5, ESP32-WROOM-32E, ESP32_WROVER-E, ESP32-DevKitC?
case 7: return F("ESP32-D0WDR2-V3"); // Max 240MHz, Dual core, QFN 5*5, ESP32-WROOM-32E, ESP32_WROVER-E, ESP32-DevKitC
}
#endif // CONFIG_IDF_TARGET_ESP32
return F("ESP32");
@ -672,16 +695,23 @@ typedef struct {
else if (2 == chip_model) { // ESP32-S2
#ifdef CONFIG_IDF_TARGET_ESP32S2
/* esptool:
def get_pkg_version(self):
def get_flash_version(self):
num_word = 3
block1_addr = self.EFUSE_BASE + 0x044
word3 = self.read_reg(block1_addr + (4 * num_word))
pkg_version = (word3 >> 21) & 0x0F
return pkg_version
def get_psram_version(self):
num_word = 3
block1_addr = self.EFUSE_BASE + 0x044
word3 = self.read_reg(block1_addr + (4 * num_word))
pkg_version = (word3 >> 28) & 0x0F
return pkg_version
*/
uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION);
uint32_t pkg_version = chip_ver & 0x7;
// uint32_t pkg_version = esp_efuse_get_pkg_ver();
uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_FLASH_VERSION);
uint32_t psram_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PSRAM_VERSION);
uint32_t pkg_version = (chip_ver & 0xF) + ((psram_ver & 0xF) * 100);
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HDW: ESP32 Model %d, Revision %d, Core %d, Package %d"), chip_info.model, chip_revision, chip_info.cores, chip_ver);
@ -690,6 +720,8 @@ typedef struct {
case 1: return F("ESP32-S2FH2"); // Max 240MHz, Single core, QFN 7*7, 2MB embedded flash, ESP32-S2-MINI-1, ESP32-S2-DevKitM-1
case 2: return F("ESP32-S2FH4"); // Max 240MHz, Single core, QFN 7*7, 4MB embedded flash
case 3: return F("ESP32-S2FN4R2"); // Max 240MHz, Single core, QFN 7*7, 4MB embedded flash, 2MB embedded PSRAM, , ESP32-S2-MINI-1U, ESP32-S2-DevKitM-1U
case 100: return F("ESP32-S2R2");
case 102: return F("ESP32-S2FNR2"); // Max 240MHz, Single core, QFN 7*7, 4MB embedded flash, 2MB embedded PSRAM, , Lolin S2 mini
}
#endif // CONFIG_IDF_TARGET_ESP32S2
return F("ESP32-S2");

View File

@ -806,7 +806,9 @@ void ResponseAppendFeatures(void)
#ifdef USE_IMPROV
feature8 |= 0x04000000; // xdrv_62_improv.ino
#endif
// feature8 |= 0x08000000;
#ifdef USE_FLOWRATEMETER
feature8 |= 0x08000000; // xsns_96_flowratemeter.ino
#endif
// feature8 |= 0x10000000;
// feature8 |= 0x20000000;

View File

@ -1242,6 +1242,19 @@ void Every250mSeconds(void)
}
}
#endif // ESP8266
#ifdef ESP32
#ifndef FIRMWARE_MINIMAL
if (EspSingleOtaPartition()) {
RtcSettings.ota_loader = 1; // Try safemode image next
SettingsSaveAll();
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING));
EspPrepRestartToSafeMode();
EspRestart();
}
#endif // FIRMWARE_MINIMAL
#endif // ESP32
char version[50];
snprintf_P(version, sizeof(version), PSTR("%s%s"), TasmotaGlobal.version, TasmotaGlobal.image_name);
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "%s %s"), full_ota_url, version);

View File

@ -617,8 +617,7 @@ void WifiConnect(void)
#endif // WIFI_RF_PRE_INIT
}
void WifiShutdown(bool option = false)
{
void WifiShutdown(bool option) {
// option = false - Legacy disconnect also used by DeepSleep
// option = true - Disconnect with SDK wifi calibrate sector erase when WIFI_FORCE_RF_CAL_ERASE enabled
delay(100); // Allow time for message xfer - disabled v6.1.0b

View File

@ -418,7 +418,7 @@ enum SettingsTextIndex { SET_OTAURL,
#endif // ESP32
SET_SHD_PARAM,
SET_RGX_SSID, SET_RGX_PASSWORD,
SET_INFLUXDB_HOST, SET_INFLUXDB_PORT, SET_INFLUXDB_ORG, SET_INFLUXDB_TOKEN, SET_INFLUXDB_BUCKET,
SET_INFLUXDB_HOST, SET_INFLUXDB_PORT, SET_INFLUXDB_ORG, SET_INFLUXDB_TOKEN, SET_INFLUXDB_BUCKET, SET_INFLUXDB_RP,
SET_MAX };
enum SpiInterfaces { SPI_NONE, SPI_MOSI, SPI_MISO, SPI_MOSI_MISO };

View File

@ -22,6 +22,150 @@
#ifdef ESP32
/*********************************************************************************************\
* [tasmota32x-safemode.bin]
* Provide an image with useful supported sensors enabled
\*********************************************************************************************/
#ifdef FIRMWARE_SAFEMODE
#define FIRMWARE_MINIMAL
#undef CODE_IMAGE_STR
#define CODE_IMAGE_STR "safemode"
#define USE_TLS
#define USE_WEBSERVER
#define USE_WEBCLIENT
#define USE_WEBCLIENT_HTTPS
#undef USE_UFILESYS
#undef GUI_TRASH_FILE
#undef GUI_EDIT_FILE
#undef USE_PING
#undef USE_AUTOCONF
#undef USE_BERRY
#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
#undef FIRMWARE_DISPLAYS // Disable tasmota-display with display drivers enabled
#undef FIRMWARE_IR // Disable tasmota-ir with IR full protocols activated
#undef FIRMWARE_WEBCAM
#undef FIRMWARE_BLUETOOTH
#undef FIRMWARE_LVGL
#undef FIRMWARE_TASMOTA32
#undef USE_IMPROV // Disable support for IMPROV serial protocol as used by esp-web-tools (+2k code)
#undef USE_TASMESH // Disable Tasmota Mesh using ESP-NOW (+11k code)
#undef USE_ARDUINO_OTA // Disable support for Arduino OTA
#undef USE_INFLUXDB // Disable influxdb support (+5k code)
#undef USE_DOMOTICZ // Disable Domoticz
#undef USE_HOME_ASSISTANT // Disable Home Assistant
#undef USE_TASMOTA_DISCOVERY // Disable Tasmota Discovery support (+2k code)
#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_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)
#undef USE_EMULATION // Disable Wemo or Hue emulation
#undef USE_EMULATION_HUE // Disable Hue Bridge emulation for Alexa (+14k code, +2k mem common)
#undef USE_EMULATION_WEMO // Disable Belkin WeMo emulation for Alexa (+6k code, +2k mem common)
#undef USE_CUSTOM // Disable Custom features
#undef USE_DISCOVERY // Disable Discovery services for both MQTT and web server
#undef USE_TIMERS // Disable support for up to 16 timers
#undef USE_TIMERS_WEB // Disable support for timer webpage
#undef USE_SUNRISE // Disable support for Sunrise and sunset tools
#undef USE_PING // Disable Ping command (+2k code)
#undef USE_UNISHOX_COMPRESSION // Disable support for string compression in Rules or Scripts
#undef USE_RULES // Disable support for rules
#undef USE_SCRIPT // Disable support for script
// -- Optional modules ----------------------------
#undef ROTARY_V1 // Disable support for MI Desk Lamp
#undef USE_SONOFF_RF // Disable support for Sonoff Rf Bridge (+3k2 code)
#undef USE_RF_FLASH // Disable support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB
#undef USE_SONOFF_SC // Disable support for Sonoff Sc (+1k1 code)
#undef USE_TUYA_MCU // Disable support for Tuya Serial MCU
#undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code)
#undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer and Sonoff L1 (+2k code)
#undef USE_SONOFF_IFAN // Disable support for Sonoff iFan02 and iFan03 (+2k code)
#undef USE_BUZZER // Disable support for a buzzer (+0k6 code)
#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller
#undef USE_SHUTTER // Disable Shutter support for up to 4 shutter with different motortypes (+6k code)
#undef USE_DEEPSLEEP // Disable support for deepsleep (+1k code)
#undef USE_EXS_DIMMER // Disable support for EX-Store WiFi Dimmer
#undef USE_HOTPLUG // Disable support for HotPlug
#undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code)
#undef USE_PWM_DIMMER // Disable support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+4k5 code)
#undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer
#undef USE_KEELOQ // Disable support for Jarolift rollers by Keeloq algorithm (+4k5 code)
#undef USE_SONOFF_D1 // Disable support for Sonoff D1 Dimmer (+0k7 code)
#undef USE_SHELLY_DIMMER // Disable support for Shelly Dimmer (+3k code)
// -- Optional light modules ----------------------
#undef USE_LIGHT // Disable support for lights
#undef USE_COUNTER // Disable counters
#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices
#undef USE_DS18x20 // Disable DS18x20 sensor
#undef USE_I2C // Disable all I2C sensors and devices
#undef USE_SPI // Disable all SPI devices
#undef USE_DISPLAY // Disable Display support
#undef USE_MHZ19 // Disable support for MH-Z19 CO2 sensor
#undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor
#undef USE_PMS5003 // Disable support for PMS5003 and PMS7003 particle concentration sensor
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_HPMA // Disable support for Honeywell HPMA115S0 particle concentration sensor
#undef USE_SR04 // Disable support for HC-SR04 ultrasonic devices (+1k code)
#undef USE_DYP // Disable support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
#undef USE_TCP_BRIDGE // DIsable support for Serial to TCP bridge (+1.3k code)
#undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
#undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger
#undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
#undef USE_ZIGBEE // Disable serial communication with Zigbee CC2530 flashed with ZNP
#undef USE_RDM6300 // Disable support for RDM6300 125kHz RFID Reader (+0k8)
#undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
#undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM)
#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code)
#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver
#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7)
#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem)
#undef USE_OPENTHERM // Disable support for OpenTherm (+15k code)
#undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code)
#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface
#undef USE_AS608 // Disable support for AS608 optical and R503 capacitive fingerprint sensor (+3k4 code)
#undef USE_TFMINIPLUS // Disable support for TFmini Plus (TFmini, TFmini-S) LiDAR modules via UART interface (+0k8)
#undef USE_HRG15 // Disable support for Hydreon RG-15 Solid State Rain sensor (+1k5 code)
#undef USE_VINDRIKTNING // Disable support for IKEA VINDRIKTNING particle concentration sensor (+0k6 code)
#undef USE_ENERGY_SENSOR // Disable energy sensors
#undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor
#undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI
#undef USE_MAX31865 // Disable support for MAX31865 RTD sensors using softSPI
#undef USE_LMT01 // Disable support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code)
#undef USE_IR_REMOTE // Disable IR driver
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_HX711 // Disable support for HX711 load cell
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
#undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer
#undef USE_WINDMETER // Disable support for analog anemometer (+2k2 code)
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code)
#undef USE_A4988_STEPPER // Disable support for A4988_Stepper
#undef USE_THERMOSTAT // Disable support for Thermostat
#undef USE_PROMETHEUS // Disable support for https://prometheus.io/ metrics exporting over HTTP /metrics endpoint
#undef DEBUG_THEO // Disable debug code
#undef USE_DEBUG_DRIVER // Disable debug code
#undef USE_AC_ZERO_CROSS_DIMMER // Disable support for AC_ZERO_CROSS_DIMMER
#endif // FIRMWARE_SAFEMODE
/*********************************************************************************************\
* [tasmota32-webcam.bin]
* Provide an image with useful supported sensors enabled

View File

@ -38,6 +38,7 @@ extern "C" {
void KNX_CB_Action(message_t const &msg, void *arg);
#endif // USE_KNX
void WifiShutdown(bool option = false);
void DomoticzTempHumPressureSensor(float temp, float hum, float baro = -1);
char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0');
extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end);

View File

@ -187,6 +187,7 @@ enum UserSelectablePins {
GPIO_RESET, // Generic reset
GPIO_MS01, // Sonoff MS01 Moisture Sensor 1wire interface
GPIO_SDIO_CMD, GPIO_SDIO_CLK, GPIO_SDIO_D0, GPIO_SDIO_D1, GPIO_SDIO_D2, GPIO_SDIO_D3, // SD Card SDIO interface, including 1-bit and 4-bit modes
GPIO_FLOWRATEMETER_IN, // Flowrate Meter
GPIO_SENSOR_END };
enum ProgramSelectablePins {
@ -418,12 +419,14 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_SDIO_D1 "|"
D_SENSOR_SDIO_D2 "|"
D_SENSOR_SDIO_D3 "|"
D_SENSOR_FLOWRATEMETER "|"
;
const char kSensorNamesFixed[] PROGMEM =
D_SENSOR_USER;
#define MAX_MAX31865S 6
#define MAX_FLOWRATEMETER 2
#define MAX_A4988_MSS 3
#define MAX_WEBCAM_DATA 8
#define MAX_WEBCAM_HSD 3
@ -973,6 +976,11 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_CM11_TXD), // CM110x Serial interface
AGPIO(GPIO_CM11_RXD), // CM110x Serial interface
#endif
#if defined(USE_FLOWRATEMETER)
AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER, // Flow meter Pin
#endif
/*-------------------------------------------------------------------------------------------*\
* ESP32 specifics
\*-------------------------------------------------------------------------------------------*/

View File

@ -209,10 +209,12 @@ const char HTTP_SCRIPT_INFO_END[] PROGMEM =
#ifdef USE_UNISHOX_COMPRESSION
#include "./html_compressed/HTTP_HEAD_LAST_SCRIPT.h"
#include "./html_compressed/HTTP_HEAD_LAST_SCRIPT32.h"
#include "./html_compressed/HTTP_HEAD_STYLE1.h"
#include "./html_compressed/HTTP_HEAD_STYLE2.h"
#else
#include "./html_uncompressed/HTTP_HEAD_LAST_SCRIPT.h"
#include "./html_uncompressed/HTTP_HEAD_LAST_SCRIPT32.h"
#include "./html_uncompressed/HTTP_HEAD_STYLE1.h"
#include "./html_uncompressed/HTTP_HEAD_STYLE2.h"
#endif
@ -241,7 +243,11 @@ const char HTTP_HEAD_STYLE3[] PROGMEM =
"<body>"
"<div style='text-align:left;display:inline-block;color:#%06x;min-width:340px;'>" // COLOR_TEXT
#ifdef FIRMWARE_MINIMAL
#ifdef FIRMWARE_SAFEMODE
"<div style='text-align:center;color:#%06x;'><h3>SafeMode</h3></div>" // COLOR_TEXT_SUCCESS
#else
"<div style='text-align:center;color:#%06x;'><h3>" D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "</h3></div>" // COLOR_TEXT_WARNING
#endif
#endif
"<div style='text-align:center;color:#%06x;'><noscript>" D_NOSCRIPT "<br></noscript>" // COLOR_TITLE
/*
@ -352,7 +358,17 @@ const char HTTP_FORM_RST_UPG[] PROGMEM =
"<br><button type='submit' onclick='eb(\"f1\").style.display=\"none\";eb(\"f2\").style.display=\"block\";this.form.submit();'>" D_START " %s</button></form>"
"</fieldset>"
"</div>"
"<div id='f2' style='display:none;text-align:center;'><b>" D_UPLOAD_STARTED " ...</b></div>";
"<div id='f2' style='display:none;text-align:center;'><b>" D_UPLOAD_STARTED "...</b></div>";
// upload via factory partition
const char HTTP_FORM_RST_UPG_FCT[] PROGMEM =
"<form method='post' action='u2' enctype='multipart/form-data'>"
"<br><input type='file' name='u2'><br>"
"<br><button type='submit' onclick='eb(\"f1\").style.display=\"none\";eb(\"f3\").style.display=\"block\";return upl(this);'>" D_START " %s</button></form>"
"</fieldset>"
"</div>"
"<div id='f3' style='display:none;text-align:center;'><b>" D_UPLOAD_FACTORY "...</b></div>"
"<div id='f2' style='display:none;text-align:center;'><b>" D_UPLOAD_STARTED "...</b></div>";
const char HTTP_FORM_CMND[] PROGMEM =
"<br><textarea readonly id='t1' cols='340' wrap='off'></textarea><br><br>"
@ -523,6 +539,9 @@ const WebServerDispatch_t WebServerDispatch[] PROGMEM = {
{ "u1", HTTP_ANY, HandleUpgradeFirmwareStart }, // OTA
{ "u2", HTTP_OPTIONS, HandlePreflightRequest },
{ "u3", HTTP_ANY, HandleUploadDone },
#ifdef ESP32
{ "u4", HTTP_GET, HandleSwitchFactory },
#endif // ESP32
{ "mn", HTTP_GET, HandleManagement },
{ "cs", HTTP_GET, HandleConsole },
{ "cs", HTTP_OPTIONS, HandlePreflightRequest },
@ -841,7 +860,11 @@ void WSContentSendStyle_P(const char* formatP, ...) {
WSContentSend_P(HTTP_SCRIPT_COUNTER);
}
}
#ifdef ESP32
WSContentSend_P(HTTP_HEAD_LAST_SCRIPT32);
#else
WSContentSend_P(HTTP_HEAD_LAST_SCRIPT);
#endif
WSContentSend_P(HTTP_HEAD_STYLE1, WebColor(COL_FORM), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_INPUT),
WebColor(COL_INPUT_TEXT), WebColor(COL_CONSOLE), WebColor(COL_CONSOLE_TEXT), WebColor(COL_BACKGROUND));
@ -860,7 +883,11 @@ void WSContentSendStyle_P(const char* formatP, ...) {
}
WSContentSend_P(HTTP_HEAD_STYLE3, WebColor(COL_TEXT),
#ifdef FIRMWARE_MINIMAL
#ifdef FIRMWARE_SAFEMODE
WebColor(COL_TEXT_SUCCESS),
#else
WebColor(COL_TEXT_WARNING),
#endif
#endif
WebColor(COL_TITLE),
(Web.initial_config) ? "" : ModuleName().c_str(), SettingsText(SET_DEVICENAME));
@ -2283,7 +2310,15 @@ void HandleRestoreConfiguration(void)
WSContentStart_P(PSTR(D_RESTORE_CONFIGURATION));
WSContentSendStyle();
WSContentSend_P(HTTP_FORM_RST);
#ifdef ESP32
if (EspSingleOtaPartition() && !EspRunningFactoryPartition()) {
WSContentSend_P(HTTP_FORM_RST_UPG_FCT, PSTR(D_RESTORE));
} else {
WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_RESTORE));
}
#else
WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_RESTORE));
#endif
if (WifiIsInManagerMode()) {
WSContentSpaceButton(BUTTON_MAIN);
} else {
@ -2508,7 +2543,15 @@ void HandleUpgradeFirmware(void) {
WSContentStart_P(PSTR(D_FIRMWARE_UPGRADE));
WSContentSendStyle();
WSContentSend_P(HTTP_FORM_UPG, SettingsText(SET_OTAURL));
#ifdef ESP32
if (EspSingleOtaPartition() && !EspRunningFactoryPartition()) {
WSContentSend_P(HTTP_FORM_RST_UPG_FCT, PSTR(D_UPGRADE));
} else {
WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_UPGRADE));
}
#else
WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_UPGRADE));
#endif
WSContentSpaceButton(BUTTON_MAIN);
WSContentStop();
@ -2884,6 +2927,80 @@ void HandlePreflightRequest(void)
/*-------------------------------------------------------------------------------------------*/
#ifdef ESP32
// Check if we are in single-mode OTA, if so restart to factory mode
//
// Parameter `u4` is either `fct` or `ota` to switch to factory or ota
//
// The page can return the followinf (code 200)
// `false`: the current partition is not the target, but a restart to factory is triggered (polling required)
// `true`: the current partition is the one required
// `none`: there is no factory partition
// return a simple status page as text/plain code 200
static void WSReturnSimpleString(const char *msg) {
if (nullptr == msg) { msg = ""; }
Webserver->client().flush();
WSHeaderSend();
Webserver->send(200, "text/plain", msg);
}
void HandleSwitchFactory(void)
{
if (!HttpCheckPriviledgedAccess()) { return; }
char tmp1[8];
WebGetArg(PSTR("u4"), tmp1, sizeof(tmp1));
bool switch_factory = false; // trigger a restart to factory partition?
bool switch_ota = false; // switch back to OTA partition
bool single_ota = false;
bool api_mode = Webserver->hasArg("api"); // api-mode, returns `true`, `false` or `none`
// switch to factory ?
if (EspSingleOtaPartition()) {
single_ota = true;
if (strcmp("fct", tmp1) == 0 && !EspRunningFactoryPartition()) {
switch_factory = true;
}
// switch to OTA
else if (strcmp("ota", tmp1) == 0 && EspRunningFactoryPartition()) {
switch_ota = true;
}
}
// apply the change in flash and return result
if (switch_factory || switch_ota) {
SettingsSaveAll();
if (switch_factory) {
EspPrepRestartToSafeMode();
} else {
const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr);
esp_ota_set_boot_partition(partition);
}
if (api_mode) {
WSReturnSimpleString("false");
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTART));
EspRestart();
} else {
WebRestart(0);
}
} else {
if (api_mode) {
// return `none` or `true`
WSReturnSimpleString(EspSingleOtaPartition() ? "true" : "none");
} else {
Webserver->sendHeader("Location", "/", true);
Webserver->send(302, "text/plain", "");
}
}
Web.upload_file_type = UPL_TASMOTA;
}
#endif // ESP32
/*-------------------------------------------------------------------------------------------*/
void HandleHttpCommand(void)
{
if (!HttpCheckPriviledgedAccess(false)) { return; }

View File

@ -70,20 +70,20 @@ extern "C" {
int32_t l_publish(struct bvm *vm) {
return be_mqtt_publish(vm, true);
}
}
int32_t be_mqtt_publish(struct bvm *vm) {
return be_mqtt_publish(vm, false);
}
int32_t be_mqtt_publish(struct bvm *vm) {
return be_mqtt_publish(vm, false);
}
void be_mqtt_subscribe(const char* topic) {
if (!topic) { return; }
MqttSubscribe(topic);
}
void be_mqtt_subscribe(const char* topic) {
if (!topic) { return; }
MqttSubscribe(topic);
}
void be_mqtt_unsubscribe(const char* topic) {
if (!topic) { return; }
MqttUnsubscribe(topic);
void be_mqtt_unsubscribe(const char* topic) {
if (!topic) { return; }
MqttUnsubscribe(topic);
}
}
#endif // USE_BERRY

View File

@ -381,7 +381,7 @@ extern "C" {
if (top == 2 && be_isstring(vm, 2)) {
const char *msg = be_tostring(vm, 2);
strlcpy(XdrvMailbox.command, msg, CMDSZ);
be_return_nil(vm); // Return nil when something goes wrong
be_return_nil(vm);
}
be_raise(vm, kTypeError, nullptr);
}
@ -394,7 +394,7 @@ extern "C" {
const char *msg = be_tostring(vm, 2);
be_pop(vm, top); // avoid Error be_top is non zero message
ResponseAppend_P(PSTR("%s"), msg);
be_return_nil(vm); // Return nil when something goes wrong
be_return_nil(vm);
}
be_raise(vm, kTypeError, nullptr);
}

View File

@ -75,6 +75,10 @@ const char berry_prog[] =
"import tapp "
#ifdef USE_BERRY_DEBUG
"import debug "
"import solidify "
#endif
;
#endif // USE_BERRY

View File

@ -108,12 +108,14 @@ extern "C" {
// If event == nullptr, then take XdrvMailbox.data
bool callBerryRule(const char *event, bool teleperiod) {
if (berry.rules_busy) { return false; }
bool save_rules_busy = berry.rules_busy;
bool exec_rule = !save_rules_busy; // true if the rule is executed, false if we only record the value
// if (berry.rules_busy) { return false; }
berry.rules_busy = true;
char * json_event = XdrvMailbox.data;
bool serviced = false;
serviced = callBerryEventDispatcher(teleperiod ? "tele" : "rule", nullptr, 0, event ? event : XdrvMailbox.data);
berry.rules_busy = false;
serviced = callBerryEventDispatcher(teleperiod ? "tele" : "rule", nullptr, exec_rule, event ? event : XdrvMailbox.data);
berry.rules_busy = save_rules_busy;
return serviced; // TODO event not handled
}

View File

@ -39,8 +39,7 @@
* IfxToken - Set Influxdb v2 and token
* IfxPeriod - Set Influxdb period. If not set (or 0), use Teleperiod
* IfxSensor - Set Influxdb sensor logging off (0) or on (1)
*
* Set influxdb update interval with command teleperiod
* IfxRP - Set Influxdb retention policy
*
* The following triggers result in automatic influxdb numeric feeds without appended time:
* - this driver initiated state message
@ -73,6 +72,9 @@
#ifndef INFLUXDB_BUCKET
#define INFLUXDB_BUCKET "db" // [IfxDatabase, IfxBucket] Influxdb v1 database or v2 bucket
#endif
#ifndef INFLUXDB_RP
#define INFLUXDB_RP "" // [IfxRP] Influxdb v1 retention policy (blank is default, usually autogen infinite)
#endif
static const char UninitializedMessage[] PROGMEM = "Unconfigured instance";
// This cannot be put to PROGMEM due to the way how it is used
@ -132,6 +134,10 @@ bool InfluxDbParameterInit(void) {
IFDB._writeUrl += "/write?db=";
IFDB._writeUrl += UrlEncode(SettingsText(SET_INFLUXDB_BUCKET));
IFDB._writeUrl += InfluxDbAuth();
if (strlen(SettingsText(SET_INFLUXDB_RP)) != 0) {
IFDB._writeUrl += "&rp=";
IFDB._writeUrl += UrlEncode(SettingsText(SET_INFLUXDB_RP));
}
}
AddLog(LOG_LEVEL_DEBUG, PSTR("IFX: Url %s"), IFDB._writeUrl.c_str());
@ -427,6 +433,7 @@ void InfluxDbLoop(void) {
#define D_CMND_INFLUXDBBUCKET "Bucket"
#define D_CMND_INFLUXDBPERIOD "Period"
#define D_CMND_INFLUXDBSENSOR "Sensor"
#define D_CMND_INFLUXDBRP "RP"
const char kInfluxDbCommands[] PROGMEM = D_PRFX_INFLUXDB "|" // Prefix
"|" D_CMND_INFLUXDBLOG "|"
@ -434,7 +441,7 @@ 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_INFLUXDBPERIOD "|" D_CMND_INFLUXDBSENSOR "|" D_CMND_INFLUXDBRP;
void (* const InfluxCommand[])(void) PROGMEM = {
&CmndInfluxDbState, &CmndInfluxDbLog,
@ -442,7 +449,7 @@ void (* const InfluxCommand[])(void) PROGMEM = {
&CmndInfluxDbUser, &CmndInfluxDbUser,
&CmndInfluxDbPassword, &CmndInfluxDbPassword,
&CmndInfluxDbDatabase, &CmndInfluxDbDatabase,
&CmndInfluxDbPeriod, &CmndInfluxDbSensor };
&CmndInfluxDbPeriod, &CmndInfluxDbSensor, &CmndInfluxDbRP };
void InfluxDbReinit(void) {
IFDB.init = false;
@ -532,6 +539,14 @@ void CmndInfluxDbDatabase(void) {
ResponseCmndChar(SettingsText(SET_INFLUXDB_BUCKET));
}
void CmndInfluxDbRP(void) {
if (XdrvMailbox.data_len > 0) {
SettingsUpdateText(SET_INFLUXDB_RP, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? PSTR(INFLUXDB_RP) : XdrvMailbox.data);
InfluxDbReinit();
}
ResponseCmndChar(SettingsText(SET_INFLUXDB_RP));
}
void CmndInfluxDbPeriod(void) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) {
Settings->influxdb_period = XdrvMailbox.payload;
@ -559,6 +574,7 @@ bool Xdrv59(uint8_t function) {
SettingsUpdateText(SET_INFLUXDB_ORG, PSTR(INFLUXDB_ORG));
SettingsUpdateText(SET_INFLUXDB_TOKEN, PSTR(INFLUXDB_TOKEN));
SettingsUpdateText(SET_INFLUXDB_BUCKET, PSTR(INFLUXDB_BUCKET));
SettingsUpdateText(SET_INFLUXDB_RP, PSTR(INFLUXDB_RP));
Settings->sbflag1.influxdb_default = 1;
}
} else if (FUNC_COMMAND == function) {

View File

@ -30,6 +30,8 @@
#define SOLAXX1_SPEED 9600 // default solax rs485 speed
#endif
#define SOLAXX1_READCONFIG // enable to read inverters config; disable to save codespace (3k1)
#define INVERTER_ADDRESS 0x0A
#define D_SOLAX_X1 "SolaxX1"
@ -44,10 +46,12 @@ const char kSolaxError[] PROGMEM =
D_SOLAX_ERROR_0 "|" D_SOLAX_ERROR_1 "|" D_SOLAX_ERROR_2 "|" D_SOLAX_ERROR_3 "|" D_SOLAX_ERROR_4 "|" D_SOLAX_ERROR_5 "|"
D_SOLAX_ERROR_6 "|" D_SOLAX_ERROR_7 "|" D_SOLAX_ERROR_8;
#ifdef SOLAXX1_READCONFIG
const char kSolaxSafetyType[] PROGMEM =
"VDE0126|ARN4105|AS4777_AU|G98/1|C10/11|OVE/ONORME8001|EN50438_NL|EN50438_DK|CEB|CEI021|NRS097_2_1|"
"VDE0126_Gr_Is|UTE_C15_712|IEC61727|G99/1|VDE0126_Gr_Co|France_VFR2014|C15_712_is_50|C15_712_is_60|"
"AS4777_NZ|RD1699|Chile|EN50438_Ireland|Philippines|Czech_PPDS|Czech_50438";
#endif // SOLAXX1_READCONFIG
union {
uint32_t ErrMessage;
@ -333,11 +337,12 @@ void solaxX1_250MSecond(void) // Every 250 milliseconds
return;
} // end received "Response for query (ID data)"
#ifdef SOLAXX1_READCONFIG
if (DataRead[6] == 0x11 && DataRead[7] == 0x84) { // received "Response for query (config data)"
if (solaxX1_global.Command_QueryConfig) {
// This values are displayed as they were received from the inverter. They are not interpreted in any way.
TempFloat = ((DataRead[9] << 8) | DataRead[10]) * 0.1f;
AddLog(LOG_LEVEL_INFO, PSTR("SX1: new wVpvStart: %1_f V (Inverter launch voltage threshold)"), &TempFloat);
AddLog(LOG_LEVEL_INFO, PSTR("SX1: wVpvStart: %1_f V (Inverter launch voltage threshold)"), &TempFloat);
AddLog(LOG_LEVEL_INFO, PSTR("SX1: wTimeStart: %d sec (launch wait time)"), (DataRead[11] << 8) | DataRead[12]);
TempFloat = ((DataRead[13] << 8) | DataRead[14]) * 0.1f;
AddLog(LOG_LEVEL_INFO, PSTR("SX1: wVacMinProtect: %1_f V (allowed minimum grid voltage)"), &TempFloat);
@ -400,6 +405,7 @@ void solaxX1_250MSecond(void) // Every 250 milliseconds
DEBUG_SENSOR_LOG(PSTR("SX1: received config data"));
return;
} // end received "Response for query (config data)"
#endif // SOLAXX1_READCONFIG
if (DataRead[6] == 0x10 && DataRead[7] == 0x80) { // received "register request"
solaxX1_global.QueryData_count = 5; // give time for next query
@ -489,9 +495,14 @@ bool SolaxX1_cmd(void)
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'."));
return false;
#endif // SOLAXX1_READCONFIG
}
AddLog(LOG_LEVEL_INFO, PSTR("SX1: Unknown command: \"%s\""),XdrvMailbox.data);
return false;
@ -510,7 +521,7 @@ const char HTTP_SNS_solaxX1_DATA2[] PROGMEM =
"{s}" D_SOLAX_X1 " " D_PV2_POWER "{m}%s " D_UNIT_WATT "{e}";
#endif
const char HTTP_SNS_solaxX1_DATA3[] PROGMEM =
"{s}" D_SOLAX_X1 " " D_UPTIME "{m}%s " D_UNIT_HOUR "{e}"
"{s}" D_SOLAX_X1 " " D_UPTIME "{m}%d " D_UNIT_HOUR "{e}"
"{s}" D_SOLAX_X1 " " D_STATUS "{m}%s"
"{s}" D_SOLAX_X1 " " D_ERROR "{m}%s"
"{s}" D_SOLAX_X1 " Inverter SN{m}%s";
@ -534,8 +545,6 @@ void solaxX1_Show(bool json)
char pv2_power[33];
dtostrfd(solaxX1.dc2_power, Settings->flag2.wattage_resolution, pv2_power);
#endif
char runtime[33];
dtostrfd(solaxX1.runtime_total, 0, runtime);
char status[33];
GetTextIndexed(status, sizeof(status), solaxX1.runMode + 1, kSolaxMode);
@ -546,8 +555,8 @@ void solaxX1_Show(bool json)
ResponseAppend_P(PSTR(",\"" D_JSON_PV2_VOLTAGE "\":%s,\"" D_JSON_PV2_CURRENT "\":%s,\"" D_JSON_PV2_POWER "\":%s"),
pv2_voltage, pv2_current, pv2_power);
#endif
ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%d,\"" D_JSON_RUNTIME "\":%s,\"" D_JSON_STATUS "\":\"%s\",\"" D_JSON_ERROR "\":%d"),
solaxX1.temperature, runtime, status, solaxX1.errorCode);
ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%d,\"" D_JSON_RUNTIME "\":%d,\"" D_JSON_STATUS "\":\"%s\",\"" D_JSON_ERROR "\":%d"),
solaxX1.temperature, solaxX1.runtime_total, status, solaxX1.errorCode);
#ifdef USE_DOMOTICZ
// Avoid bad temperature report at beginning of the day (spikes of 1200 celsius degrees)
@ -562,7 +571,7 @@ void solaxX1_Show(bool json)
#endif
WSContentSend_Temp(D_SOLAX_X1, solaxX1.temperature);
char errorCodeString[33];
WSContentSend_PD(HTTP_SNS_solaxX1_DATA3, runtime, status,
WSContentSend_PD(HTTP_SNS_solaxX1_DATA3, solaxX1.runtime_total, status,
GetTextIndexed(errorCodeString, sizeof(errorCodeString), solaxX1_ParseErrorCode(solaxX1.errorCode), kSolaxError),
solaxX1.SerialNumber);
#endif // USE_WEBSERVER

View File

@ -0,0 +1,268 @@
/*
xsns_96_flowratemeter.ino - flowratemeter support for Tasmota
- up to two flowratemeter YF-DN50 and similary
- flow rate frequencies f = 1 Hz up to 5 kHz
- uses the FreqRes resolution
Copyright (C) 2022 Norbert Richter
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 <http://www.gnu.org/licenses/>.
*/
#ifdef USE_FLOWRATEMETER
#define XSNS_96 96
#define FLOWRATEMETER_WEIGHT_AVG_SAMPLE 20 // number of samples for smooth weigted average
#define FLOWRATEMETER_MIN_FREQ 1 // Hz
#define D_JSON_FLOWRATEMETER_RATE "Rate"
#define D_JSON_FLOWRATEMETER_VALUE "Value"
#define D_JSON_FLOWRATEMETER_UNIT "Unit"
#define D_JSON_FLOWRATEMETER_VALUE_AVG "average"
#define D_JSON_FLOWRATEMETER_VALUE_RAW "raw"
#ifdef USE_WEBSERVER
const char HTTP_SNS_FLOWRATEMETER[] PROGMEM =
"{s}" D_FLOWRATEMETER_NAME "-%d{m}%*_f %s{e}"
;
#endif // USE_WEBSERVER
int32_t flowratemeter_period[MAX_FLOWRATEMETER] = {0};
float flowratemeter_period_avg[MAX_FLOWRATEMETER] = {0};
uint32_t flowratemeter_count[MAX_FLOWRATEMETER] = {0};
volatile uint32_t flowratemeter_last_irq[MAX_FLOWRATEMETER] = {0};
bool flowratemeter_valuesread = false;
bool flowratemeter_raw_value = false;
void IRAM_ATTR FlowRateMeterIR(uint16_t irq)
{
uint32_t time = micros();
#if defined(ESP8266)
uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
#endif
if (irq < MAX_FLOWRATEMETER) {
if ((time - flowratemeter_last_irq[irq]) < (1000000 / FLOWRATEMETER_MIN_FREQ)) {
flowratemeter_period[irq] = time - flowratemeter_last_irq[irq];
} else {
flowratemeter_period[irq] = 0;
}
flowratemeter_valuesread = true;
flowratemeter_last_irq[irq] = time;
}
}
// GPIO_STATUS is always 0 (?), so can only determine the IR source using this way
void IRAM_ATTR FlowRateMeter1IR(void)
{
FlowRateMeterIR(0);
}
void IRAM_ATTR FlowRateMeter2IR(void)
{
FlowRateMeterIR(1);
}
void FlowRateMeterRead(void)
{
for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
if ((micros() - flowratemeter_last_irq[i]) >= (1000000 / FLOWRATEMETER_MIN_FREQ)) {
flowratemeter_period[i] = 0;
flowratemeter_period_avg[i] = 0;
}
// exponentially weighted average
if (flowratemeter_count[i] <= FLOWRATEMETER_WEIGHT_AVG_SAMPLE) {
flowratemeter_count[i]++;
}
flowratemeter_period_avg[i] -= flowratemeter_period_avg[i] / flowratemeter_count[i];
flowratemeter_period_avg[i] += float(flowratemeter_period[i]) / flowratemeter_count[i];
}
}
void FlowRateMeterInit(void)
{
void (* irq_service[MAX_FLOWRATEMETER])(void)= {FlowRateMeter1IR, FlowRateMeter2IR};
flowratemeter_valuesread = false;
for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
pinMode(Pin(GPIO_FLOWRATEMETER_IN, i), INPUT);
attachInterrupt(Pin(GPIO_FLOWRATEMETER_IN, i), irq_service[i], RISING);
}
}
void FlowRateMeterShow(bool json)
{
if (json) {
ResponseAppend_P(PSTR(",\"" D_FLOWRATEMETER_NAME "\":{\"" D_JSON_FLOWRATEMETER_RATE "\":["));
}
for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
float flowratemeter_rate_avg_float = 0;
if (flowratemeter_period[i]) {
flowratemeter_rate_avg_float =
((Settings->SensorBits1.flowratemeter_unit ? (1000000.0 / 1000.0) : (1000000 / 60.0)) / 2.0)
/ (flowratemeter_raw_value ? flowratemeter_period[i] : flowratemeter_period_avg[i])
* (Settings->flowratemeter_calibration[i] ? (float)Settings->flowratemeter_calibration[i] : 1000.0);
}
if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
if (json) {
ResponseAppend_P(PSTR("%s%*_f"),
i ? PSTR(",") : PSTR(""),
Settings->flag2.frequency_resolution, &flowratemeter_rate_avg_float
);
#ifdef USE_WEBSERVER
} else {
WSContentSend_PD(HTTP_SNS_FLOWRATEMETER,
i+1,
Settings->flag2.frequency_resolution, &flowratemeter_rate_avg_float,
Settings->SensorBits1.flowratemeter_unit ? D_UNIT_CUBICMETER_PER_HOUR : D_UNIT_LITER_PER_MINUTE
);
#endif // USE_WEBSERVER
}
}
}
if (json) {
ResponseAppend_P(PSTR("],\"" D_JSON_FLOWRATEMETER_VALUE "\":\"%s\""),
flowratemeter_raw_value ? PSTR(D_JSON_FLOWRATEMETER_VALUE_RAW) : PSTR(D_JSON_FLOWRATEMETER_VALUE_AVG)
);
ResponseAppend_P(PSTR(",\"" D_JSON_FLOWRATEMETER_UNIT "\":\"%s\"}"),
Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBICMETER_PER_HOUR) : PSTR(D_UNIT_LITER_PER_MINUTE)
);
}
}
/*********************************************************************************************\
* Supported commands for Sensor96:
*
* Sensor96 - Show current settings
* Sensor96 0 0|1 - Show flow value in l/min (0) or m³/h (1)
* Sensor96 1 <correction-factor> - Set sensor 1 factor (x 1000) - to set to 0.2 enter 'Sensor96 1 200'
* Sensor96 2 <correction-factor> - Set sensor 2 factor (x 1000)
* Sensor96 9 0|1 - Value mode: Switch between displaying avg(0) / raw(1) readings (not permanently)
*
* Flowmeter calibration:
* - get the current displayed flow rate (D)
* - get the current <correction-factor> (c)
* - measure the real flow rate (M)
* - new <correction-factor> = M / (c * D)
*
* Example:
* - displayed flow rate = 254.39 l/min (D)
* - current <correction-factor> = 1.0 (c)
* - real flow rate = 83.42 l/min (M)
*
* new <correction-factor> = M / (c * D) = 83.42 / (1 * 254.39) = 0.328
* Cmd: Sensor96 x 328
\*********************************************************************************************/
bool FlowRateMeterCommand(void) {
bool show_parms = 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: // Unit
if (any_value) {
Settings->SensorBits1.flowratemeter_unit = value & 1;
ResponseCmndNumber(value & 1);
show_parms = false;
}
break;
case 1: // Sensor calibration value
case 2:
if (any_value) {
Settings->flowratemeter_calibration[XdrvMailbox.payload - 1] = value;
ResponseCmndNumber(value);
show_parms = false;
}
break;
case 9: // avg/raw values
if (any_value) {
flowratemeter_raw_value = value & 1;
ResponseCmndNumber(value & 1);
show_parms = false;
}
break;
}
if (show_parms) {
Response_P(PSTR("{\"Sensor%d\":{\"" D_JSON_POWERFACTOR "\":["), XSNS_96);
for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
float flowratemeter_factor = Settings->flowratemeter_calibration[i] ? (float)Settings->flowratemeter_calibration[i] / 1000 : 1;
ResponseAppend_P(PSTR("%s%3_f"), i ? PSTR(",") : PSTR(""), &flowratemeter_factor);
}
ResponseAppend_P(PSTR("],\"" D_JSON_FLOWRATEMETER_VALUE "\":\"%s\""),
flowratemeter_raw_value ? PSTR(D_JSON_FLOWRATEMETER_VALUE_RAW) : PSTR(D_JSON_FLOWRATEMETER_VALUE_AVG)
);
ResponseAppend_P(PSTR(",\"" D_JSON_FLOWRATEMETER_UNIT "\":\"%s\"}}"),
Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBICMETER_PER_HOUR) : PSTR(D_UNIT_LITER_PER_MINUTE)
);
}
return true;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xsns96(uint8_t function)
{
bool result = false;
if (PinUsed(GPIO_FLOWRATEMETER_IN, GPIO_ANY)) {
switch (function) {
case FUNC_INIT:
FlowRateMeterInit();
break;
case FUNC_EVERY_250_MSECOND:
FlowRateMeterRead();
break;
case FUNC_COMMAND_SENSOR:
if (XSNS_96 == XdrvMailbox.index) {
result = FlowRateMeterCommand();
}
break;
case FUNC_JSON_APPEND:
FlowRateMeterShow(true);
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
FlowRateMeterShow(false);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_FLOWRATEMETER

View File

@ -298,5 +298,14 @@ BL6523_TX = GPIO_BL6523_TX
BL6523_RX = GPIO_BL6523_RX
ADE7880_IRQ = GPIO_ADE7880_IRQ
RESET = GPIO_RESET
MS01 = GPIO_MS01
SDIO_CMD = GPIO_SDIO_CMD
SDIO_CLK = GPIO_SDIO_CLK
SDIO_D0 = GPIO_SDIO_D0
SDIO_D1 = GPIO_SDIO_D1
SDIO_D2 = GPIO_SDIO_D2
SDIO_D3 = GPIO_SDIO_D3
FLOWRATEMETER_SIGNAL = GPIO_FLOWRATEMETER_IN
SENSOR_END = GPIO_SENSOR_END