mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-28 05:06:32 +00:00
Merge branch 'development' into prerelease-14.6.0
This commit is contained in:
commit
87449961bc
@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file.
|
|||||||
- AlpineJS 2.8.2 - optional for now (#23259)
|
- AlpineJS 2.8.2 - optional for now (#23259)
|
||||||
- Support for XMODEM over serial and telnet if enabled with `#define USE_XYZMODEM`
|
- Support for XMODEM over serial and telnet if enabled with `#define USE_XYZMODEM`
|
||||||
- PZEM_AC device address in JSON and GUI (#23268)
|
- PZEM_AC device address in JSON and GUI (#23268)
|
||||||
|
- Filesystem command ``UfsList[2]``
|
||||||
|
- ESP32 show network interface priority in `Status 5` debug logging (#23302)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
- HASPmota added `y2_min` and `y2_max` to control the second series of `chart` (#23287)
|
- HASPmota added `y2_min` and `y2_max` to control the second series of `chart` (#23287)
|
||||||
|
@ -116,6 +116,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||||||
|
|
||||||
## Changelog v14.6.0 Ryan
|
## Changelog v14.6.0 Ryan
|
||||||
### Added
|
### Added
|
||||||
|
- Filesystem command ``UfsList[2]``
|
||||||
- Extend command `GPIO` with different display options and allowing updating of module GPIO's in one go
|
- Extend command `GPIO` with different display options and allowing updating of module GPIO's in one go
|
||||||
- Support Vango Technologies V924x ultralow power, single-phase, power measurement [#23127](https://github.com/arendst/Tasmota/issues/23127)
|
- Support Vango Technologies V924x ultralow power, single-phase, power measurement [#23127](https://github.com/arendst/Tasmota/issues/23127)
|
||||||
- Support for HLK-LD2402 24GHz smart wave motion sensor [#23133](https://github.com/arendst/Tasmota/issues/23133)
|
- Support for HLK-LD2402 24GHz smart wave motion sensor [#23133](https://github.com/arendst/Tasmota/issues/23133)
|
||||||
@ -124,6 +125,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||||||
- PZEM_AC device address in JSON and GUI [#23268](https://github.com/arendst/Tasmota/issues/23268)
|
- PZEM_AC device address in JSON and GUI [#23268](https://github.com/arendst/Tasmota/issues/23268)
|
||||||
- Allow acl in mqtt when client certificate is in use with `#define USE_MQTT_CLIENT_CERT` [#22998](https://github.com/arendst/Tasmota/issues/22998)
|
- Allow acl in mqtt when client certificate is in use with `#define USE_MQTT_CLIENT_CERT` [#22998](https://github.com/arendst/Tasmota/issues/22998)
|
||||||
- AlpineJS 2.8.2 - optional for now [#23259](https://github.com/arendst/Tasmota/issues/23259)
|
- AlpineJS 2.8.2 - optional for now [#23259](https://github.com/arendst/Tasmota/issues/23259)
|
||||||
|
- ESP32 show network interface priority in `Status 5` debug logging [#23302](https://github.com/arendst/Tasmota/issues/23302)
|
||||||
- Berry experimental driver for AXP2101 for M5Core2v1.1 [#23039](https://github.com/arendst/Tasmota/issues/23039)
|
- Berry experimental driver for AXP2101 for M5Core2v1.1 [#23039](https://github.com/arendst/Tasmota/issues/23039)
|
||||||
- Berry `tasmota.when_network_up()` and simplified Matter using it [#23057](https://github.com/arendst/Tasmota/issues/23057)
|
- Berry `tasmota.when_network_up()` and simplified Matter using it [#23057](https://github.com/arendst/Tasmota/issues/23057)
|
||||||
- Berry `introspect.solidified()` to know if a Berry object is solidified or in RAM [#23063](https://github.com/arendst/Tasmota/issues/23063)
|
- Berry `introspect.solidified()` to know if a Berry object is solidified or in RAM [#23063](https://github.com/arendst/Tasmota/issues/23063)
|
||||||
|
@ -648,9 +648,23 @@ String DNSGetIPStr(uint32_t idx)
|
|||||||
|
|
||||||
//
|
//
|
||||||
#include "lwip/dns.h"
|
#include "lwip/dns.h"
|
||||||
|
#ifdef ESP32
|
||||||
|
#include "esp_netif_net_stack.h"
|
||||||
|
#endif
|
||||||
void WifiDumpAddressesIPv6(void)
|
void WifiDumpAddressesIPv6(void)
|
||||||
{
|
{
|
||||||
for (netif* intf = netif_list; intf != nullptr; intf = intf->next) {
|
for (netif* intf = netif_list; intf != nullptr; intf = intf->next) {
|
||||||
|
#ifdef ESP32
|
||||||
|
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(intf);
|
||||||
|
int32_t route_prio = esp_netif ? esp_netif_get_route_prio(esp_netif) : -1;
|
||||||
|
if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c%i' IPv4 %s (%i)", intf->name[0], intf->name[1], intf->num, IPAddress(&intf->ip_addr).toString(true).c_str(), route_prio);
|
||||||
|
for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
|
||||||
|
if (!ip_addr_isany_val(intf->ip6_addr[i]))
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, "IP : '%c%c%i' IPv6 %s %s (%i)", intf->name[0], intf->name[1], intf->num,
|
||||||
|
IPAddress(&intf->ip6_addr[i]).toString(true).c_str(),
|
||||||
|
ip_addr_islinklocal(&intf->ip6_addr[i]) ? "local" : "", route_prio);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c%i' IPv4 %s", intf->name[0], intf->name[1], intf->num, IPAddress(&intf->ip_addr).toString(true).c_str());
|
if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c%i' IPv4 %s", intf->name[0], intf->name[1], intf->num, IPAddress(&intf->ip_addr).toString(true).c_str());
|
||||||
for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
|
for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
|
||||||
if (!ip_addr_isany_val(intf->ip6_addr[i]))
|
if (!ip_addr_isany_val(intf->ip6_addr[i]))
|
||||||
@ -658,7 +672,9 @@ void WifiDumpAddressesIPv6(void)
|
|||||||
IPAddress(&intf->ip6_addr[i]).toString(true).c_str(),
|
IPAddress(&intf->ip6_addr[i]).toString(true).c_str(),
|
||||||
ip_addr_islinklocal(&intf->ip6_addr[i]) ? "local" : "");
|
ip_addr_islinklocal(&intf->ip6_addr[i]) ? "local" : "");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
AddLog(LOG_LEVEL_DEBUG, "IP : DNS: %s %s", IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString(true).c_str());
|
AddLog(LOG_LEVEL_DEBUG, "IP : DNS: %s %s", IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString(true).c_str());
|
||||||
AddLog(LOG_LEVEL_DEBUG, "WIF: v4IP: %_I v6IP: %s mainIP: %s", (uint32_t) WiFi.localIP(), WifiGetIPv6Str().c_str(), WifiGetIPStr().c_str());
|
AddLog(LOG_LEVEL_DEBUG, "WIF: v4IP: %_I v6IP: %s mainIP: %s", (uint32_t) WiFi.localIP(), WifiGetIPv6Str().c_str(), WifiGetIPStr().c_str());
|
||||||
//#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET)
|
//#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET)
|
||||||
|
@ -791,6 +791,7 @@ bool XYZModemLoop(void) {
|
|||||||
if (millis() > XYZModem.timeout) {
|
if (millis() > XYZModem.timeout) {
|
||||||
XYZModem.timeout = millis() + (2 * 1000); // Protocol 10 second receive timeout - here 2 seconds
|
XYZModem.timeout = millis() + (2 * 1000); // Protocol 10 second receive timeout - here 2 seconds
|
||||||
XYZModemSendNakOrC();
|
XYZModemSendNakOrC();
|
||||||
|
XYZModem.nak_count--;
|
||||||
if (XYZModemReadAvailable(1)) { // Timeout after 1 second
|
if (XYZModemReadAvailable(1)) { // Timeout after 1 second
|
||||||
XYZModem.nak_count = (XYZModem.oldChecksum) ? 10 : 3;
|
XYZModem.nak_count = (XYZModem.oldChecksum) ? 10 : 3;
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("XMD: Receive started"));
|
AddLog(LOG_LEVEL_DEBUG, PSTR("XMD: Receive started"));
|
||||||
|
@ -373,6 +373,17 @@ uint8_t UfsReject(char *name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return true if SDC
|
||||||
|
bool UfsIsSDC(void) {
|
||||||
|
#ifndef SDC_HIDE_INVISIBLES
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
if (((uint32_t)ufsp != (uint32_t)ffsp) && ((uint32_t)ffsp == (uint32_t)dfsp)) return false;
|
||||||
|
if (((uint32_t)ufsp == (uint32_t)ffsp) && (ufs_type != UFS_TSDC)) return false;
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Tfs low level functions
|
* Tfs low level functions
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
@ -478,8 +489,10 @@ bool TfsDeleteFile(const char *fname) {
|
|||||||
if (!ffs_type) { return false; }
|
if (!ffs_type) { return false; }
|
||||||
|
|
||||||
if (!ffsp->remove(fname)) {
|
if (!ffsp->remove(fname)) {
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("TFS: Delete failed"));
|
if (!ffsp->rmdir(fname)) {
|
||||||
return false;
|
AddLog(LOG_LEVEL_INFO, PSTR("TFS: Delete failed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -912,7 +925,7 @@ char* UfsFilename(char* fname, char* fname_in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char kUFSCommands[] PROGMEM = "Ufs|" // Prefix
|
const char kUFSCommands[] PROGMEM = "Ufs|" // Prefix
|
||||||
"|Type|Size|Free|Delete|Rename|Run"
|
"|Type|Size|Free|Delete|Rename|Run|List"
|
||||||
#ifdef UFILESYS_STATIC_SERVING
|
#ifdef UFILESYS_STATIC_SERVING
|
||||||
"|Serve"
|
"|Serve"
|
||||||
#endif
|
#endif
|
||||||
@ -922,7 +935,7 @@ const char kUFSCommands[] PROGMEM = "Ufs|" // Prefix
|
|||||||
;
|
;
|
||||||
|
|
||||||
void (* const kUFSCommand[])(void) PROGMEM = {
|
void (* const kUFSCommand[])(void) PROGMEM = {
|
||||||
&UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete, &UFSRename, &UFSRun
|
&UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete, &UFSRename, &UFSRun, &UFSList
|
||||||
#ifdef UFILESYS_STATIC_SERVING
|
#ifdef UFILESYS_STATIC_SERVING
|
||||||
,&UFSServe
|
,&UFSServe
|
||||||
#endif
|
#endif
|
||||||
@ -973,7 +986,7 @@ void UFSDelete(void) {
|
|||||||
if (ffs_type && (ffs_type != ufs_type) && (2 == XdrvMailbox.index)) {
|
if (ffs_type && (ffs_type != ufs_type) && (2 == XdrvMailbox.index)) {
|
||||||
result = TfsDeleteFile(fname);
|
result = TfsDeleteFile(fname);
|
||||||
} else {
|
} else {
|
||||||
result = (ufs_type && ufsp->remove(fname));
|
result = (ufs_type && (ufsp->remove(fname) || ufsp->rmdir(fname)));
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
ResponseCmndFailed();
|
ResponseCmndFailed();
|
||||||
@ -1009,6 +1022,65 @@ void UFSRename(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UFSListDir(char *path, bool hide_dot) {
|
||||||
|
bool update = false;
|
||||||
|
|
||||||
|
File dir = dfsp->open(path, UFS_FILE_READ);
|
||||||
|
if (dir) {
|
||||||
|
dir.rewindDirectory();
|
||||||
|
char *ep;
|
||||||
|
while (true) {
|
||||||
|
File entry = dir.openNextFile();
|
||||||
|
if (!entry) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// esp32 returns path here, shorten to filename
|
||||||
|
ep = (char*)entry.name();
|
||||||
|
if (*ep == '/') { ep++; }
|
||||||
|
char *lcp = strrchr(ep,'/');
|
||||||
|
if (lcp) {
|
||||||
|
ep = lcp + 1;
|
||||||
|
}
|
||||||
|
if (hide_dot && (*ep == '.')) { continue; }
|
||||||
|
|
||||||
|
// osx formatted disks contain a lot of stuff we dont want
|
||||||
|
bool hiddable = UfsReject((char*)ep);
|
||||||
|
if (!hiddable || !UfsIsSDC() ) {
|
||||||
|
String tstr = "";
|
||||||
|
if (!entry.isDirectory()) { // ESP32 does not support isFile()
|
||||||
|
uint32_t tm = entry.getLastWrite();
|
||||||
|
tstr = GetDT(tm);
|
||||||
|
}
|
||||||
|
ResponseAppend_P(PSTR("%c[\"%s\",\"%s\",%d]"), (!update)?'[':',', EscapeJSONString(ep).c_str(), tstr.c_str(), entry.size());
|
||||||
|
update = true;
|
||||||
|
entry.close();
|
||||||
|
|
||||||
|
yield(); // trigger watchdog reset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir.close();
|
||||||
|
}
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UFSList(void) {
|
||||||
|
// UfsList - List all non-dot files and directories in root directory
|
||||||
|
// UfsList / - List all non-dot files and directories in root directory
|
||||||
|
// UfsList2 - List all files and directories in root directory
|
||||||
|
// UfsList /dir1 - List all non-dot files and directories in directory dir1
|
||||||
|
bool hide_dot = (XdrvMailbox.index != 2);
|
||||||
|
strcpy(ufs_path, "/");
|
||||||
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
strlcpy(ufs_path, XdrvMailbox.data, sizeof(ufs_path));
|
||||||
|
}
|
||||||
|
ResponseCmnd();
|
||||||
|
if (UFSListDir(ufs_path, hide_dot)) {
|
||||||
|
ResponseAppend_P(PSTR("]}"));
|
||||||
|
} else {
|
||||||
|
ResponseCmndDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef UFILESYS_STATIC_SERVING
|
#ifdef UFILESYS_STATIC_SERVING
|
||||||
/*
|
/*
|
||||||
* Serves a filesystem folder at a web url.
|
* Serves a filesystem folder at a web url.
|
||||||
@ -1183,8 +1255,6 @@ void UFSRun(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Web support
|
* Web support
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
@ -1387,7 +1457,7 @@ void UfsDirectory(void) {
|
|||||||
#ifdef GUI_EDIT_FILE
|
#ifdef GUI_EDIT_FILE
|
||||||
WSContentSend_P(UFS_FORM_FILE_UPGb, ufs_path);
|
WSContentSend_P(UFS_FORM_FILE_UPGb, ufs_path);
|
||||||
#endif
|
#endif
|
||||||
if (!isSDC()) {
|
if (!UfsIsSDC()) {
|
||||||
WSContentSend_P(UFS_FORM_FILE_UPGb1);
|
WSContentSend_P(UFS_FORM_FILE_UPGb1);
|
||||||
}
|
}
|
||||||
WSContentSend_P(UFS_FORM_FILE_UPGb2);
|
WSContentSend_P(UFS_FORM_FILE_UPGb2);
|
||||||
@ -1398,17 +1468,6 @@ void UfsDirectory(void) {
|
|||||||
Web.upload_file_type = UPL_UFSFILE;
|
Web.upload_file_type = UPL_UFSFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if SDC
|
|
||||||
bool isSDC(void) {
|
|
||||||
#ifndef SDC_HIDE_INVISIBLES
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
if (((uint32_t)ufsp != (uint32_t)ffsp) && ((uint32_t)ffsp == (uint32_t)dfsp)) return false;
|
|
||||||
if (((uint32_t)ufsp == (uint32_t)ffsp) && (ufs_type != UFS_TSDC)) return false;
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void UfsListDir(char *path, uint8_t depth) {
|
void UfsListDir(char *path, uint8_t depth) {
|
||||||
char name[48];
|
char name[48];
|
||||||
char npath[128];
|
char npath[128];
|
||||||
@ -1462,7 +1521,7 @@ void UfsListDir(char *path, uint8_t depth) {
|
|||||||
// osx formatted disks contain a lot of stuff we dont want
|
// osx formatted disks contain a lot of stuff we dont want
|
||||||
bool hiddable = UfsReject((char*)ep);
|
bool hiddable = UfsReject((char*)ep);
|
||||||
|
|
||||||
if (!hiddable || !isSDC() ) {
|
if (!hiddable || !UfsIsSDC() ) {
|
||||||
|
|
||||||
for (uint8_t cnt = 0; cnt<depth; cnt++) {
|
for (uint8_t cnt = 0; cnt<depth; cnt++) {
|
||||||
*cp++ = '-';
|
*cp++ = '-';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user