Merge branch 'development' into prerelease-15.0.0

This commit is contained in:
Theo Arends 2025-06-11 09:20:16 +02:00
commit 59911c3467
6 changed files with 2062 additions and 1988 deletions

View File

@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file.
- Berry `compile` and `tasmota.compile` option to compile in local context (#23457)
- Support for AP33772S USB PD Sink Controller as used in CentyLab RotoPD
- Berry mqtt publish rule processing
- Berry `tasmota.is_network_up()`
### Changed
- ESP32 Platform from 2025.04.30 to 2025.05.40, Framework (Arduino Core) from v3.1.3.250411 to v3.2.0.250504 and IDF from v5.3.2.250403 to v5.4.1.250501 (#23397)

View File

@ -184,6 +184,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
exec_cmd, closure(class_Tasmota_exec_cmd_closure)
gc, closure(class_Tasmota_gc_closure)
event, closure(class_Tasmota_event_closure)
is_network_up, closure(class_Tasmota_is_network_up_closure)
when_network_up, closure(class_Tasmota_when_network_up_closure)
run_network_up, closure(class_Tasmota_run_network_up_closure)
add_driver, closure(class_Tasmota_add_driver_closure)

View File

@ -724,12 +724,16 @@ class Tasmota
end
end
# returns `true` if the network stack is connected
def is_network_up()
return tasmota.wifi()['up'] || tasmota.eth()['up']
end
# add a closure to the list to be called when network is connected
# or call immediately if network is already up
def when_network_up(cl)
self.check_not_method(cl)
var is_connected = tasmota.wifi()['up'] || tasmota.eth()['up']
if is_connected
if self.is_network_up()
cl() # call closure
else
if (self._wnu == nil)
@ -743,8 +747,7 @@ class Tasmota
# run all pending closures when network is up
def run_network_up()
if (self._wnu == nil) return end
var is_connected = tasmota.wifi()['up'] || tasmota.eth()['up']
if is_connected
if self.is_network_up()
# run all closures in a safe loop
while (size(self._wnu) > 0)
var cl = self._wnu[0]
@ -760,13 +763,12 @@ class Tasmota
end
def event(event_type, cmd, idx, payload, raw)
import introspect
if event_type=='every_50ms'
if (event_type == 'every_50ms')
if (self._wnu) self.run_network_up() end # capture when network becomes connected
self.run_timers()
end #- first run deferred events -#
if event_type=='every_250ms'
if (event_type == 'every_250ms')
self.run_cron()
end
@ -777,11 +779,12 @@ class Tasmota
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, bool(idx))
elif event_type=='gc' return self.gc()
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, bool(idx))
elif (event_type == 'gc') return self.gc()
elif self._drivers
import introspect
var i = 0
while i < size(self._drivers)
var d = self._drivers[i]
@ -811,6 +814,16 @@ class Tasmota
return done
end
######################################################################
# add_driver
#
# Add an instance to the dispatchin of Berry events
#
# Args:
# - `d`: instance (or driver)
# The events will be dispatched to this instance whenever
# it has a method with the same name of the instance
######################################################################
def add_driver(d)
if type(d) != 'instance'
raise "value_error", "instance required"

View File

@ -2469,6 +2469,11 @@ void SyslogAsync(bool refresh) {
and below message in syslog if hostname starts with a "z"
2023-12-17T00:09:52.797782+01:00 domus8 rsyslogd: Uncompression of a message failed with return code -3 - enable debug logging if you need further information. Message ignored. [v8.2302.0]
Notice in both cases the date and time is taken from the syslog server
Example of rsyslog filter using rsyslog properties:
:programname, startswith, "ESP-" /var/log/udp-logs/esp.log # Log in esp.log
:programname, startswith, "ESP-" stop # Do not log in syslog
*/
// snprintf_P(header, sizeof(header), PSTR("%s ESP-"), NetworkHostname());
@ -2483,6 +2488,10 @@ void SyslogAsync(bool refresh) {
LOG_LEVEL_INFO 2 -> severity level 6 - Informational
LOG_LEVEL_DEBUG 3 -> severity level 7 - Debug
LOG_LEVEL_DEBUG_MORE 4 -> severity level 7 - Debug
Example of rsyslog filter using rsyslog properties:
:programname, startswith, "ESP-" /var/log/udp-logs/esp.log # Log in esp.log
:programname, startswith, "ESP-" stop # Do not log in syslog
*/
// snprintf_P(header, sizeof(header), PSTR("<%d>%s ESP-"), 128 + min(loglevel * 3, 7), NetworkHostname());
@ -2493,6 +2502,10 @@ void SyslogAsync(bool refresh) {
SYSLOG-MSG = <134>Jan 1 00:00:02 wemos5 ESP-HTP: Web server active on wemos5 with IP address 192.168.2.172
Result = 2023-01-01T00:00:02+01:00 wemos5 ESP-HTP: Web server active on wemos5 with IP address 192.168.2.172
Notice Year is taken from syslog server. Month, day and time is provided by Tasmota device. No milliseconds
Example of rsyslog filter using rsyslog properties:
:programname, startswith, "ESP-" /var/log/udp-logs/esp.log # Log in esp.log
:programname, startswith, "ESP-" stop # Do not log in syslog
*/
// snprintf_P(header, sizeof(header), PSTR("<134>%s %s ESP-"), GetSyslogDate(line).c_str(), NetworkHostname());
@ -2500,16 +2513,21 @@ void SyslogAsync(bool refresh) {
uint32_t msg_len = len -mxtime -1;
/* RFC5424 - Syslog protocol - <PRI>VERSION TIMESTAMP HOSTNAME APP_NAME PROCID STRUCTURED-DATA MSGID MSG
<PRI> = Facility 16 (= local use 0), Severity 6 (= informational) => 16 * 8 + 6 = <134>
VERSION = 1
<PRI>[5] = Facility 16 (= local use 0), Severity 6 (= informational) => 16 * 8 + 6 = <134>
VERSION[2] = 1
TIMESTAMP = yyyy-mm-ddThh:mm:ss.nnnnnn-hh:mm (= local with timezone)
APP_NAME = tasmota
PROCID = -
HOSTNAME[255] = wemos5
APP_NAME[48] = tasmota
PROCID[128] = -
STRUCTURED-DATA = -
MSGID = HTP:
SYSLOG-MSG = <134>1 1970-01-01T00:00:02.096000+01:00 wemos5 Tasmota - - ESP-HTP: Web server active on wemos5 with IP address 192.168.2.172
Result = 1970-01-01T00:00:02.096000+00:00 wemos5 Tasmota ESP-HTP: Web server active on wemos5 with IP address 192.168.2.172
MSGID[32] = HTP:
SYSLOG-MSG = <134>1 1970-01-01T00:00:02.096000+01:00 wemos5 tasmota - - HTP: Web server active on wemos5 with IP address 192.168.2.172
Result = 1970-01-01T00:00:02.096000+00:00 wemos5 tasmota HTP: Web server active on wemos5 with IP address 192.168.2.172
Notice date and time is provided by Tasmota device.
Example of rsyslog filter using rsyslog properties:
:programname, isequal, "tasmota" /var/log/udp-logs/esp.log # Log in esp.log
:programname, isequal, "tasmota" stop # Do not log in syslog
*/
char timestamp[mxtime];
subStr(timestamp, line, " ", 1); // 00:00:02.096-026
@ -2520,19 +2538,29 @@ void SyslogAsync(bool refresh) {
GetDate().c_str(), timestamp, GetTimeZone().c_str(), // 1970-01-01T00:00:02.096000+01:00
NetworkHostname());
*/
/*
// msgid is currently not well supported in rsyslog (https://github.com/rsyslog/rsyslog/issues/3592#issuecomment-480186237)
char msgid[5];
char* line_msgid = strchr(msg_start, ' ');
if (line_msgid - msg_start < sizeof(msgid)) { // Only 3 character message ids supported
if (line_msgid && (line_msgid - msg_start < sizeof(msgid))) { // Only 3 character message ids supported
subStr(msgid, msg_start, " ", 1); // HTP:
msg_start += strlen(msgid);
msg_len -= strlen(msgid);
} else {
strcpy(msgid, "-"); // -
}
*/
char msgid[2] = { 0 };
char* line_msgid = strchr(msg_start, ':');
if ((line_msgid == nullptr) || (line_msgid - msg_start != 3)) { // Only 3 character message id supported
strcpy(msgid, "-"); // -
}
snprintf_P(header, sizeof(header), PSTR("<%d>1 %s%s000%s %s tasmota - - %s"),
128 + min(loglevel * 3, 7), // Error (1) = 131, Info (2) = 134, Debug (3) = 135, DebugMore = (4) 135
GetDate().c_str(), timestamp, GetTimeZone().c_str(), // 1970-01-01T00:00:02.096000+01:00
NetworkHostname(), msgid);
/*
TasConsole.printf("Loglevel ");
TasConsole.print(loglevel);

View File

@ -292,6 +292,7 @@ void Script_ticker4_end(void) {
#define SCRIPT_UDP_BUFFER_SIZE 128
#endif
#define SCRIPT_UDP_PORT 1999
#endif
// EEPROM MACROS
// i2c eeprom
@ -1529,6 +1530,7 @@ char *script;
}
#ifdef USE_SCRIPT_GLOBVARS
int32_t udp_call(char *url, uint32_t port, char *sbuf) {
WiFiUDP udp;
IPAddress adr;
@ -1597,20 +1599,22 @@ void Script_PollUdp(void) {
if (glob_script_mem.udp_flags.udp_connected ) {
uint32_t timeout = millis();
while (1) {
char *packet_buffer = glob_script_mem.packet_buffer;
uint16_t plen = glob_script_mem.Script_PortUdp.parsePacket();
if (!plen || plen > glob_script_mem.pb_size) {
glob_script_mem.Script_PortUdp.flush();
if (plen > 0) {
glob_script_mem.Script_PortUdp.read(packet_buffer, glob_script_mem.pb_size - 1);
glob_script_mem.Script_PortUdp.flush();
}
break;
}
// not more then 500 ms
if (millis() - timeout > 500) { break;}
char *packet_buffer = glob_script_mem.packet_buffer;
int32_t len = glob_script_mem.Script_PortUdp.read(packet_buffer, glob_script_mem.pb_size);
int32_t len = glob_script_mem.Script_PortUdp.read(packet_buffer, glob_script_mem.pb_size - 1);
packet_buffer[len] = 0;
glob_script_mem.script_udp_remote_ip = glob_script_mem.Script_PortUdp.remoteIP();
#ifdef SCRIPT_DEBUG_UDP
//AddLog(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str());
AddLog(LOG_LEVEL_DEBUG, PSTR("UDP: received Packet %s - %d - %_I"), packet_buffer, len, (uint32_t)glob_script_mem.script_udp_remote_ip);
#endif
char *lp = packet_buffer;
@ -1706,7 +1710,12 @@ void script_udp_sendvar(char *vname, TS_FLOAT *fp, char *sp, uint16_t alen) {
if (!glob_script_mem.udp_flags.udp_used) return;
if (!glob_script_mem.udp_flags.udp_connected) return;
char sbuf[SCRIPT_MAX_SBSIZE + 4];
uint16_t ubsiz = SCRIPT_MAX_SBSIZE + 16;
if (ubsiz < 32) {
ubsiz = 32;
}
char sbuf[ubsiz];
strcpy(sbuf, "=>");
strcat(sbuf, vname);
if (glob_script_mem.udp_flags.udp_binary_payload == 0 || !fp) {
@ -8218,10 +8227,14 @@ startline:
and_or = 0;
if (if_exe[ifstck - 1] == 0) {
// not enabled
#if 0
glob_script_mem.FLAGS.ignore_line = 1;
/*
// AddLog(LOG_LEVEL_INFO, PSTR(">>> %d"),ifstck);
#else
// AddLog(LOG_LEVEL_INFO, PSTR(">>> %d"),ifstck);
while (*lp) {
if (*lp == SCRIPT_EOL) {
lp--;
break;
}
if (*lp == '{') {
@ -8232,7 +8245,7 @@ startline:
lp++;
}
goto next_line;
*/
#endif
}
} else if (!strncmp(lp, "then", 4) && if_state[ifstck] == 1) {
lp += 4;