Merge branch 'development' into prerelease-15.0.1

This commit is contained in:
Theo Arends 2025-06-14 12:22:14 +02:00
commit d42deb39a1
11 changed files with 143 additions and 28 deletions

View File

@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file.
## [Released]
## [15.0.1] 20250614
- Release Sharon
## [15.0.0.1] 20250614
### Fixed
- LVGL regression missing `lv.ANIM_OFF` and `lv.ANIM_ON` (#23544)
- Berry fix `realline` (#23546)
- LVGL HASPmota fix regression introduced with LVGL 9.3.0 (#23547)
## [15.0.0] 20250613
- Release Sharon

View File

@ -75,7 +75,7 @@ Latest released binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release
Historical binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release-15.0.0
- http://ota.tasmota.com/tasmota/release-15.0.1
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
@ -104,7 +104,7 @@ Latest released binaries can be downloaded from
- https://ota.tasmota.com/tasmota32/release
Historical binaries can be downloaded from
- https://ota.tasmota.com/tasmota32/release-15.0.0
- https://ota.tasmota.com/tasmota32/release-15.0.1
The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin``
@ -114,6 +114,12 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
[Complete list](BUILDS.md) of available feature and sensors.
## Changelog v15.0.1 Sharon
### Fixed
- Berry fix `realline` [#23546](https://github.com/arendst/Tasmota/issues/23546)
- LVGL regression missing `lv.ANIM_OFF` and `lv.ANIM_ON` [#23544](https://github.com/arendst/Tasmota/issues/23544)
- LVGL HASPmota fix regression introduced with LVGL 9.3.0 [#23547](https://github.com/arendst/Tasmota/issues/23547)
## Changelog v15.0.0 Sharon
### Added
- Provide serial upload port from VSC to PIO [#23436](https://github.com/arendst/Tasmota/issues/23436)
@ -136,8 +142,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- HASPmota `antiburn()` [#23400](https://github.com/arendst/Tasmota/issues/23400)
- HASPmota auto-dimming when no touch [#23425](https://github.com/arendst/Tasmota/issues/23425)
### Breaking Changed
### Changed
- ESP8266 platform update from 2024.09.00 to 2025.05.00 [#23448](https://github.com/arendst/Tasmota/issues/23448)
- ESP32 Platform from 2025.04.30 to 2025.05.30, Framework (Arduino Core) from v3.1.3.250411 to v3.1.3.250504 and IDF from v5.3.2.250403 to v5.3.3.250501 [#23404](https://github.com/arendst/Tasmota/issues/23404)
@ -164,5 +168,3 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- LVGL Tasmota logo splash screen [#23538](https://github.com/arendst/Tasmota/issues/23538)
- Matter and mDNS can be enabled at the same time [#23373](https://github.com/arendst/Tasmota/issues/23373)
- Haspmota `haspmota.parse()` page parsing [#23403](https://github.com/arendst/Tasmota/issues/23403)
### Removed

View File

@ -316,10 +316,12 @@ char* be_fgets(void *hfile, void *buffer, int size)
if (hfile != nullptr && buffer != nullptr && size > 0) {
File * f_ptr = (File*) hfile;
int ret = f_ptr->readBytesUntil('\n', buf, size - 1);
// Serial.printf("be_fgets size=%d ret=%d\n", size, ret);
// Serial.printf("be_fgets size=%d ret=%d, tell=%i, fsize=%i\n", size, ret, f_ptr->position(), f_ptr->size());
if (ret >= 0) {
buf[ret] = 0; // add string terminator
if ((ret != 0) && (ret < size - 1)) {
if ((ret == 0) && (f_ptr->position() >= f_ptr->size())) {
return NULL;
} else if (ret < size - 1) {
buf[ret] = '\n';
buf[ret+1] = 0;
}
@ -327,7 +329,7 @@ char* be_fgets(void *hfile, void *buffer, int size)
}
}
#endif // USE_UFILESYS
return nullptr;
return NULL;
// return fgets(buffer, size, hfile);
}

View File

@ -237,6 +237,8 @@ const be_const_member_t lv0_constants[] = {
{ "ALIGN_TOP_MID", be_cconst_int(LV_ALIGN_TOP_MID) },
{ "ALIGN_TOP_RIGHT", be_cconst_int(LV_ALIGN_TOP_RIGHT) },
{ "ANIM_IMAGE_PART_MAIN", be_cconst_int(LV_ANIM_IMAGE_PART_MAIN) },
{ "ANIM_OFF", be_cconst_int(LV_ANIM_OFF) },
{ "ANIM_ON", be_cconst_int(LV_ANIM_ON) },
{ "ANIM_PLAYTIME_INFINITE", be_cconst_int(LV_ANIM_PLAYTIME_INFINITE) },
{ "ANIM_REPEAT_INFINITE", be_cconst_int(LV_ANIM_REPEAT_INFINITE) },
{ "ARC_MODE_NORMAL", be_cconst_int(LV_ARC_MODE_NORMAL) },

View File

@ -183,6 +183,8 @@ LV_LABEL_LONG_DOT=LV_LABEL_LONG_MODE_DOTS
LV_LABEL_LONG_SCROLL=LV_LABEL_LONG_MODE_SCROLL
LV_LABEL_LONG_SCROLL_CIRCULAR=LV_LABEL_LONG_MODE_SCROLL_CIRCULAR
LV_LABEL_LONG_CLIP=LV_LABEL_LONG_MODE_CLIP
LV_ANIM_OFF=LV_ANIM_OFF
LV_ANIM_ON=LV_ANIM_ON
// ======================================================================
// Generated from headers

View File

@ -508,6 +508,8 @@ LV_LABEL_LONG_DOT=LV_LABEL_LONG_MODE_DOTS
LV_LABEL_LONG_SCROLL=LV_LABEL_LONG_MODE_SCROLL
LV_LABEL_LONG_SCROLL_CIRCULAR=LV_LABEL_LONG_MODE_SCROLL_CIRCULAR
LV_LABEL_LONG_CLIP=LV_LABEL_LONG_MODE_CLIP
LV_ANIM_OFF=LV_ANIM_OFF
LV_ANIM_ON=LV_ANIM_ON
// ======================================================================
// Generated from headers

View File

@ -24,6 +24,8 @@ lv.ALIGN_TOP_LEFT = 1
lv.ALIGN_TOP_MID = 2
lv.ALIGN_TOP_RIGHT = 3
lv.ANIM_IMAGE_PART_MAIN = 0
lv.ANIM_OFF = 0
lv.ANIM_ON = 1
lv.ANIM_PLAYTIME_INFINITE = -1
lv.ANIM_REPEAT_INFINITE = -1
lv.ARC_MODE_NORMAL = 0
@ -428,11 +430,16 @@ lv.KEY_PREV = 11
lv.KEY_RIGHT = 19
lv.KEY_UP = 17
lv.LABEL_DOT_NUM = 3
lv.LABEL_LONG_CLIP = 4
lv.LABEL_LONG_DOT = 1
lv.LABEL_LONG_MODE_CLIP = 4
lv.LABEL_LONG_MODE_DOTS = 1
lv.LABEL_LONG_MODE_SCROLL = 2
lv.LABEL_LONG_MODE_SCROLL_CIRCULAR = 3
lv.LABEL_LONG_MODE_WRAP = 0
lv.LABEL_LONG_SCROLL = 2
lv.LABEL_LONG_SCROLL_CIRCULAR = 3
lv.LABEL_LONG_WRAP = 0
lv.LABEL_POS_LAST = 65535
lv.LABEL_TEXT_SELECTION_OFF = 65535
lv.LAYER_TYPE_NONE = 0

View File

@ -2153,12 +2153,12 @@ class lvh_spangroup : lvh_obj
# label do not need a sub-label
def post_init(jline)
self._lv_obj.set_mode(lv.SPAN_MODE_BREAK) # use lv.SPAN_MODE_BREAK by default
self._lv_obj.refr_mode()
self._lv_obj.refresh()
super(self).post_init(jline) # call super -- not needed
end
# refresh mode
def refr_mode()
self._lv_obj.refr_mode()
def refresh()
self._lv_obj.refresh()
end
end
@ -2176,7 +2176,7 @@ class lvh_span : lvh_root
# check if it is the parent is a spangroup
if isinstance(self._parent_lvh, self._page._hm.lvh_spangroup)
# print(">>> GOOD")
self._lv_obj = self._parent_lvh._lv_obj.new_span()
self._lv_obj = self._parent_lvh._lv_obj.add_span()
self._style = self._lv_obj.get_style()
else
print("HSP: 'span' should have a parent of type 'spangroup'")
@ -2194,7 +2194,7 @@ class lvh_span : lvh_root
var font = self.parse_font(t)
if font != nil
self._style.set_text_font(font)
self._parent_lvh.refr_mode()
self._parent_lvh.refresh()
end
end
@ -2271,7 +2271,7 @@ class lvh_span : lvh_root
# invoke
try
f(self._style, v)
self._parent_lvh.refr_mode()
self._parent_lvh.refresh()
except .. as e, m
raise e, m + " for " + k
end
@ -2522,19 +2522,19 @@ class lvh_chart : lvh_obj
end
def set_y_min(_y_min)
self._y_min = _y_min
self._lv_obj.set_range(lv.CHART_AXIS_PRIMARY_Y, self._y_min, self._y_max)
self._lv_obj.set_axis_range(lv.CHART_AXIS_PRIMARY_Y, self._y_min, self._y_max)
end
def set_y_max(_y_max)
self._y_max = _y_max
self._lv_obj.set_range(lv.CHART_AXIS_PRIMARY_Y, self._y_min, self._y_max)
self._lv_obj.set_axis_range(lv.CHART_AXIS_PRIMARY_Y, self._y_min, self._y_max)
end
def set_y2_min(_y2_min)
self._y2_min = _y2_min
self._lv_obj.set_range(lv.CHART_AXIS_SECONDARY_Y, self._y2_min, self._y2_max)
self._lv_obj.set_axis_range(lv.CHART_AXIS_SECONDARY_Y, self._y2_min, self._y2_max)
end
def set_y2_max(_y2_max)
self._y2_max = _y2_max
self._lv_obj.set_range(lv.CHART_AXIS_SECONDARY_Y, self._y2_min, self._y2_max)
self._lv_obj.set_axis_range(lv.CHART_AXIS_SECONDARY_Y, self._y2_min, self._y2_max)
end
def set_series1_color(color)

View File

@ -9520,7 +9520,7 @@ static const bvalue be_ktab_class_lvh_spangroup[6] = {
/* K1 */ be_nested_str_weak(set_mode),
/* K2 */ be_nested_str_weak(lv),
/* K3 */ be_nested_str_weak(SPAN_MODE_BREAK),
/* K4 */ be_nested_str_weak(refr_mode),
/* K4 */ be_nested_str_weak(refresh),
/* K5 */ be_nested_str_weak(post_init),
};
@ -9566,9 +9566,9 @@ be_local_closure(class_lvh_spangroup_post_init, /* name */
/********************************************************************
** Solidified function: refr_mode
** Solidified function: refresh
********************************************************************/
be_local_closure(class_lvh_spangroup_refr_mode, /* name */
be_local_closure(class_lvh_spangroup_refresh, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
@ -9579,7 +9579,7 @@ be_local_closure(class_lvh_spangroup_refr_mode, /* name */
NULL, /* no sub protos */
1, /* has constants */
&be_ktab_class_lvh_spangroup, /* shared constants */
be_str_weak(refr_mode),
be_str_weak(refresh),
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
@ -9601,7 +9601,7 @@ be_local_class(lvh_spangroup,
&be_class_lvh_obj,
be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(refr_mode, -1), be_const_closure(class_lvh_spangroup_refr_mode_closure) },
{ be_const_key_weak(refresh, -1), be_const_closure(class_lvh_spangroup_refresh_closure) },
{ be_const_key_weak(_lv_class, -1), be_const_class(be_class_lv_spangroup) },
{ be_const_key_weak(post_init, 0), be_const_closure(class_lvh_spangroup_post_init_closure) },
})),
@ -9627,14 +9627,14 @@ static const bvalue be_ktab_class_lvh_span[31] = {
/* K15 */ be_nested_str_weak(is_color_attribute),
/* K16 */ be_nested_str_weak(parse_color),
/* K17 */ be_nested_str_weak(_parent_lvh),
/* K18 */ be_nested_str_weak(refr_mode),
/* K18 */ be_nested_str_weak(refresh),
/* K19 */ be_nested_str_weak(_X20for_X20),
/* K20 */ be_nested_str_weak(HSP_X3A_X20Could_X20not_X20find_X20function_X20set_),
/* K21 */ be_nested_str_weak(_lv_obj),
/* K22 */ be_nested_str_weak(_page),
/* K23 */ be_nested_str_weak(_hm),
/* K24 */ be_nested_str_weak(lvh_spangroup),
/* K25 */ be_nested_str_weak(new_span),
/* K25 */ be_nested_str_weak(add_span),
/* K26 */ be_nested_str_weak(get_style),
/* K27 */ be_nested_str_weak(HSP_X3A_X20_X27span_X27_X20should_X20have_X20a_X20parent_X20of_X20type_X20_X27spangroup_X27),
/* K28 */ be_nested_str_weak(parse_font),
@ -10632,7 +10632,7 @@ be_local_class(lvh_tab,
static const bvalue be_ktab_class_lvh_chart[29] = {
/* K0 */ be_nested_str_weak(_y_min),
/* K1 */ be_nested_str_weak(_lv_obj),
/* K2 */ be_nested_str_weak(set_range),
/* K2 */ be_nested_str_weak(set_axis_range),
/* K3 */ be_nested_str_weak(lv),
/* K4 */ be_nested_str_weak(CHART_AXIS_PRIMARY_Y),
/* K5 */ be_nested_str_weak(_y_max),

View File

@ -0,0 +1,89 @@
# LoRaWAN Decoder file for Dragino DDS75-LB/LS
#
# References
# User Manual: https://wiki.dragino.com/xwiki/bin/view/Main/User%20Manual%20for%20LoRaWAN%20End%20Nodes/DDS75-LB_LoRaWAN_Distance_Detection_Sensor_User_Manual/
# TTN Device Repository: https://github.com/TheThingsNetwork/lorawan-devices/blob/master/vendor/dragino/dds75-lb.js
import string
global.dds75lbNodes = {}
class LwDecoDDS75LB
static def decodeUplink(Node, RSSI, FPort, Bytes)
var data = {"Device":"Dragino DDS75-LB/LS"}
data.insert("Node", Node)
var valid_values = false
var last_seen = 1451602800
var battery_last_seen = 1451602800
var battery = 1000
var rssi = RSSI
var distance = 0
if global.dds75lbNodes.find(Node)
last_seen = global.dds75lbNodes.item(Node)[1]
battery_last_seen = global.dds75lbNodes.item(Node)[2]
battery = global.dds75lbNodes.item(Node)[3]
rssi = global.dds75lbNodes.item(Node)[4]
distance = global.dds75lbNodes.item(Node)[5]
end
## SENSOR DATA ##
if 2 == FPort && 8 == Bytes.size() && 0 == ( Bytes[0] & 0x10 )
last_seen = tasmota.rtc('local')
battery_last_seen = tasmota.rtc('local')
battery = ((Bytes[0] << 8) | Bytes[1]) / 1000.0
data.insert("BattV",battery)
distance=Bytes[2]<<8 | Bytes[3]
data.insert("Distance",distance)
valid_values = true
## STATUS DATA ##
elif 5 == FPort && 7 == Bytes.size()
data.insert("Sensor_Model",Bytes[0])
data.insert("Firmware_Version", f'v{Bytes[1]:%u}.{Bytes[2]>>4:%u}.{Bytes[2]&0xF:%u}')
data.insert("Freq_Band",LwRegions[Bytes[3]-1])
data.insert("Sub_Band",Bytes[4])
battery_last_seen = tasmota.rtc('local')
battery = ((Bytes[5] << 8) | Bytes[6]) / 1000.0
valid_values = true
else
# Ignore other Fports
end #Fport
if valid_values
if global.dds75lbNodes.find(Node)
global.dds75lbNodes.remove(Node)
end
# sensor[0] [1] [2] [3] [4] [5]
global.dds75lbNodes.insert(Node, [Node, last_seen, battery_last_seen, battery, RSSI, distance])
end
return data
end #decodeUplink()
static def add_web_sensor()
var msg = ""
for sensor: global.dds75lbNodes
var name = string.format("DDS75-L-%i", sensor[0])
var name_tooltip = "Dragino DDS75-L"
var last_seen = sensor[1]
var battery_last_seen = sensor[2]
var battery = sensor[3]
var rssi = sensor[4]
msg += lwdecode.header(name, name_tooltip, battery, battery_last_seen, rssi, last_seen)
# Sensors
var distance = sensor[5]
msg += "<tr class='htr'><td colspan='4'>&#9478;" # |
msg += string.format(" &#11123;&#xFE0F; %.0fmm", distance) # ⭳
msg += "{e}" # = </td></tr>
end
return msg
end #add_web_sensor()
end #class
LwDeco = LwDecoDDS75LB

View File

@ -22,6 +22,6 @@
#define TASMOTA_SHA_SHORT // Filled by Github sed
const uint32_t TASMOTA_VERSION = 0x0F000000; // 15.0.0.0
const uint32_t TASMOTA_VERSION = 0x0F000100; // 15.0.1.0
#endif // _TASMOTA_VERSION_H_