From f759e2698831653083e3cad1d26e9378cb657da8 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Fri, 8 Jan 2021 21:36:05 +0100
Subject: [PATCH 01/71] remove backward compatible #define option; ITurned it
into an undocumented option to suppress it
---
tasmota/xdrv_49_pid.ino | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index 37b8774a3..eda2b633f 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -119,11 +119,6 @@
#define PID_REPORT_MORE_SETTINGS // If defined, the SENSOR output will provide more extensive json
// output in the PID section
-// #define PID_BACKWARD_COMPATIBLE // Preserve the backward compatible reporting of PID power via
- // `%topic%/PID {"power":"0.000"}` This is now available in
- // `%topic$/SENSOR {..., "PID":{"PidPower":0.00}}`
- // Don't use unless you know that you need it
-
* Help with using the PID algorithm and with loop tuning can be found at
* http://blog.clanlaw.org.uk/2018/01/09/PID-tuning-with-node-red-contrib-pid.html
* This is directed towards using the algorithm in the node-red node node-red-contrib-pid but the algorithm here is based on
@@ -362,14 +357,14 @@ void PIDShowValues(void) {
static void run_pid()
{
double power = pid.tick(pid_current_time_secs);
-#ifdef PID_BACKWARD_COMPATIBLE
+#ifdef PID_DONT_USE_PID_TOPIC
// This part is left inside to regularly publish the PID Power via
// `%topic%/PID {"power":"0.000"}`
char str_buf[FLOATSZ];
dtostrfd(power, 3, str_buf);
snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s\":\"%s\"}"), "power", str_buf);
MqttPublishPrefixTopic_P(TELE, "PID", false);
-#endif // PID_BACKWARD_COMPATIBLE
+#endif // PID_DONT_USE_PID_TOPIC
#if defined PID_SHUTTER
// send output as a position from 0-100 to defined shutter
From aedfe35b017567e28d06fd724699450235d67790 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Fri, 8 Jan 2021 21:36:28 +0100
Subject: [PATCH 02/71] re-add code to modify timeprop values via mqtt
---
tasmota/xdrv_48_timeprop.ino | 51 ++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/tasmota/xdrv_48_timeprop.ino b/tasmota/xdrv_48_timeprop.ino
index 6e8537dbb..a457c8d94 100644
--- a/tasmota/xdrv_48_timeprop.ino
+++ b/tasmota/xdrv_48_timeprop.ino
@@ -82,6 +82,11 @@
# include "Timeprop.h"
+#define D_CMND_TIMEPROP "timeprop_"
+#define D_CMND_TIMEPROP_SETPOWER "setpower_" // add index no on end (0:8) and data is power 0:1
+
+enum TimepropCommands { CMND_TIMEPROP_SETPOWER };
+const char kTimepropCommands[] PROGMEM = D_CMND_TIMEPROP_SETPOWER;
static Timeprop timeprops[TIMEPROP_NUM_OUTPUTS];
static int relayNos[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_RELAYS};
@@ -143,7 +148,50 @@ void Timeprop_Xdrv_Power() {
/* } XdrvMailbox; */
// To get here post with topic cmnd/timeprop_setpower_n where n is index into timeprops 0:7
+bool Timeprop_Command()
+{
+ char command [CMDSZ];
+ bool serviced = true;
+ uint8_t ua_prefix_len = strlen(D_CMND_TIMEPROP); // to detect prefix of command
+ /*
+ snprintf_P(log_data, sizeof(log_data), "Command called: "
+ "index: %d data_len: %d payload: %d topic: %s data: %s\n",
+ XdrvMailbox.index,
+ XdrvMailbox.data_len,
+ XdrvMailbox.payload,
+ (XdrvMailbox.payload >= 0 ? XdrvMailbox.topic : ""),
+ (XdrvMailbox.data_len >= 0 ? XdrvMailbox.data : ""));
+ AddLog(LOG_LEVEL_INFO);
+ */
+ if (0 == strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_TIMEPROP), ua_prefix_len)) {
+ // command starts with timeprop_
+ int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + ua_prefix_len, kTimepropCommands);
+ if (CMND_TIMEPROP_SETPOWER == command_code) {
+ /*
+ snprintf_P(log_data, sizeof(log_data), "Timeprop command timeprop_setpower: "
+ "index: %d data_len: %d payload: %d topic: %s data: %s",
+ XdrvMailbox.index,
+ XdrvMailbox.data_len,
+ XdrvMailbox.payload,
+ (XdrvMailbox.payload >= 0 ? XdrvMailbox.topic : ""),
+ (XdrvMailbox.data_len >= 0 ? XdrvMailbox.data : ""));
+ AddLog(LOG_LEVEL_INFO);
+ */
+ if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS) {
+ timeprops[XdrvMailbox.index].setPower( atof(XdrvMailbox.data), timeprop_current_time_secs );
+ }
+ snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"" D_CMND_TIMEPROP D_CMND_TIMEPROP_SETPOWER "%d\":\"%s\"}"),
+ XdrvMailbox.index, XdrvMailbox.data);
+ }
+ else {
+ serviced = false;
+ }
+ } else {
+ serviced = false;
+ }
+ return serviced;
+}
/*********************************************************************************************\
* Interface
@@ -162,6 +210,9 @@ bool Xdrv48(byte function)
case FUNC_EVERY_SECOND:
Timeprop_Every_Second();
break;
+ case FUNC_COMMAND:
+ result = Timeprop_Command();
+ break;
case FUNC_SET_POWER:
Timeprop_Xdrv_Power();
break;
From d966f1f74f3469567d91997e9b45f5f7f148149c Mon Sep 17 00:00:00 2001
From: Marcus
Date: Fri, 8 Jan 2021 21:57:56 +0100
Subject: [PATCH 03/71] add ifndef to ensure "tasmota-minimal" still builds
---
tasmota/xdrv_48_timeprop.ino | 3 +++
tasmota/xdrv_49_pid.ino | 2 ++
2 files changed, 5 insertions(+)
diff --git a/tasmota/xdrv_48_timeprop.ino b/tasmota/xdrv_48_timeprop.ino
index a457c8d94..f11d5e46b 100644
--- a/tasmota/xdrv_48_timeprop.ino
+++ b/tasmota/xdrv_48_timeprop.ino
@@ -79,6 +79,7 @@
#ifdef USE_TIMEPROP
+#ifndef FIRMWARE_MINIMAL
# include "Timeprop.h"
@@ -153,6 +154,7 @@ bool Timeprop_Command()
char command [CMDSZ];
bool serviced = true;
uint8_t ua_prefix_len = strlen(D_CMND_TIMEPROP); // to detect prefix of command
+ AddLog_P(LOG_LEVEL_ERROR, PSTR("TRP: Timeprop_Command called"));
/*
snprintf_P(log_data, sizeof(log_data), "Command called: "
"index: %d data_len: %d payload: %d topic: %s data: %s\n",
@@ -220,4 +222,5 @@ bool Xdrv48(byte function)
return result;
}
+#endif // FIRMWARE_MINIMAL
#endif // USE_TIMEPROP
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index eda2b633f..fdc02ea50 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -129,6 +129,7 @@
#ifdef USE_PID
+#ifndef FIRMWARE_MINIMAL
#include "PID.h"
@@ -410,4 +411,5 @@ bool Xdrv49(byte function)
}
return result;
}
+#endif // FIRMWARE_MINIMAL
#endif // USE_PID
From 2e76946e2daab4c9f968d6931f0641bc79eef8db Mon Sep 17 00:00:00 2001
From: Marcus
Date: Sat, 9 Jan 2021 18:05:54 +0100
Subject: [PATCH 04/71] add missing Response to SetPv
---
tasmota/xdrv_49_pid.ino | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index fdc02ea50..529ca3913 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -237,6 +237,7 @@ void CmndSetPv(void) {
// this runs it at the next second
run_pid_now = true;
}
+ ResponseCmndNumber(atof(XdrvMailbox.data));
}
void CmndSetSp(void) {
@@ -358,7 +359,7 @@ void PIDShowValues(void) {
static void run_pid()
{
double power = pid.tick(pid_current_time_secs);
-#ifdef PID_DONT_USE_PID_TOPIC
+#ifndef PID_DONT_USE_PID_TOPIC
// This part is left inside to regularly publish the PID Power via
// `%topic%/PID {"power":"0.000"}`
char str_buf[FLOATSZ];
From 1fd5c44e6c16d1cadcd2315ca882e748592d10b8 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Sat, 9 Jan 2021 18:23:07 +0100
Subject: [PATCH 05/71] add missing response; fix exclusion of PID power
---
tasmota/xdrv_49_pid.ino | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index fdc02ea50..529ca3913 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -237,6 +237,7 @@ void CmndSetPv(void) {
// this runs it at the next second
run_pid_now = true;
}
+ ResponseCmndNumber(atof(XdrvMailbox.data));
}
void CmndSetSp(void) {
@@ -358,7 +359,7 @@ void PIDShowValues(void) {
static void run_pid()
{
double power = pid.tick(pid_current_time_secs);
-#ifdef PID_DONT_USE_PID_TOPIC
+#ifndef PID_DONT_USE_PID_TOPIC
// This part is left inside to regularly publish the PID Power via
// `%topic%/PID {"power":"0.000"}`
char str_buf[FLOATSZ];
From 5a165962664b4ebf2294465d6433288e99f4b384 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Sun, 10 Jan 2021 15:47:26 +0100
Subject: [PATCH 06/71] update code size metrics
---
tasmota/my_user_config.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 5040f6c09..0eb76da95 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -811,10 +811,10 @@
// -- Prometheus exporter ---------------------------
//#define USE_PROMETHEUS // Add support for https://prometheus.io/ metrics exporting over HTTP /metrics endpoint
-// -- PID and Timeprop ------------------------------
-// #define use TIMEPROP // Add support for the timeprop feature (+0k8 code)
+// -- PID and Timeprop ------------------------------ // Both together will add +12k1 code
+// #define use TIMEPROP // Add support for the timeprop feature (+9k1 code)
// For details on the configuration please see the header of tasmota/xdrv_48_timeprop.ino
-// #define USE_PID // Add suport for the PID feature (+11k1 code)
+// #define USE_PID // Add suport for the PID feature (+11k2 code)
// For details on the configuration please see the header of tasmota/xdrv_49_pid.ino
// -- End of general directives -------------------
From be68e1cdb1dd99aec84469744816a9e5b2a58844 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Fri, 8 Jan 2021 21:36:05 +0100
Subject: [PATCH 07/71] remove backward compatible #define option; Turned it
into an undocumented option to suppress it
---
tasmota/xdrv_49_pid.ino | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index 7da87ac7d..9d851b285 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -117,11 +117,6 @@
#define PID_REPORT_MORE_SETTINGS // If defined, the SENSOR output will provide more extensive json
// output in the PID section
-// #define PID_BACKWARD_COMPATIBLE // Preserve the backward compatible reporting of PID power via
- // `%topic%/PID {"power":"0.000"}` This is now available in
- // `%topic$/SENSOR {..., "PID":{"PidPower":0.00}}`
- // Don't use unless you know that you need it
-
* Help with using the PID algorithm and with loop tuning can be found at
* http://blog.clanlaw.org.uk/2018/01/09/PID-tuning-with-node-red-contrib-pid.html
* This is directed towards using the algorithm in the node-red node node-red-contrib-pid but the algorithm here is based on
@@ -391,14 +386,14 @@ void PIDShowValues(void) {
void PIDRun(void) {
double power = Pid.pid.tick(Pid.current_time_secs);
-#ifdef PID_BACKWARD_COMPATIBLE
+#ifdef PID_DONT_USE_PID_TOPIC
// This part is left inside to regularly publish the PID Power via
// `%topic%/PID {"power":"0.000"}`
char str_buf[FLOATSZ];
dtostrfd(power, 3, str_buf);
snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"%s\":\"%s\"}"), "power", str_buf);
MqttPublishPrefixTopic_P(TELE, "PID", false);
-#endif // PID_BACKWARD_COMPATIBLE
+#endif // PID_DONT_USE_PID_TOPIC
#if defined PID_SHUTTER
// send output as a position from 0-100 to defined shutter
From 405f25db08b055014e0d941edb032f5043f42473 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Fri, 8 Jan 2021 21:36:28 +0100
Subject: [PATCH 08/71] re-add code to modify timeprop values via mqtt
---
tasmota/xdrv_48_timeprop.ino | 59 +++++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/tasmota/xdrv_48_timeprop.ino b/tasmota/xdrv_48_timeprop.ino
index bddf2653f..10fd3e843 100644
--- a/tasmota/xdrv_48_timeprop.ino
+++ b/tasmota/xdrv_48_timeprop.ino
@@ -81,6 +81,16 @@
* Publish values between 0 and 1 to the topic(s) described above
\*********************************************************************************************/
+#define D_CMND_TIMEPROP "timeprop_"
+#define D_CMND_TIMEPROP_SETPOWER "setpower_" // add index no on end (0:8) and data is power 0:1
+
+enum TimepropCommands { CMND_TIMEPROP_SETPOWER };
+const char kTimepropCommands[] PROGMEM = D_CMND_TIMEPROP_SETPOWER;
+
+static Timeprop timeprops[TIMEPROP_NUM_OUTPUTS];
+static int relayNos[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_RELAYS};
+static long currentRelayStates = 0; // current actual relay states. Bit 0 first relay
+
#ifndef TIMEPROP_NUM_OUTPUTS
#define TIMEPROP_NUM_OUTPUTS 1 // how many outputs to control (with separate alogorithm for each)
#endif
@@ -162,7 +172,51 @@ void TimepropXdrvPower(void) {
/* char *data; */
/* } XdrvMailbox; */
-// To get here post with topic cmnd/timeprop_setpower_n where n is index into Tprop.timeprops 0:7
+// To get here post with topic cmnd/timeprop_setpower_n where n is index into timeprops 0:7
+bool TimepropCommand()
+{
+ char command [CMDSZ];
+ bool serviced = true;
+ uint8_t ua_prefix_len = strlen(D_CMND_TIMEPROP); // to detect prefix of command
+ /*
+ snprintf_P(log_data, sizeof(log_data), "Command called: "
+ "index: %d data_len: %d payload: %d topic: %s data: %s\n",
+ XdrvMailbox.index,
+ XdrvMailbox.data_len,
+ XdrvMailbox.payload,
+ (XdrvMailbox.payload >= 0 ? XdrvMailbox.topic : ""),
+ (XdrvMailbox.data_len >= 0 ? XdrvMailbox.data : ""));
+
+ AddLog(LOG_LEVEL_INFO);
+ */
+ if (0 == strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_TIMEPROP), ua_prefix_len)) {
+ // command starts with timeprop_
+ int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + ua_prefix_len, kTimepropCommands);
+ if (CMND_TIMEPROP_SETPOWER == command_code) {
+ /*
+ snprintf_P(log_data, sizeof(log_data), "Timeprop command timeprop_setpower: "
+ "index: %d data_len: %d payload: %d topic: %s data: %s",
+ XdrvMailbox.index,
+ XdrvMailbox.data_len,
+ XdrvMailbox.payload,
+ (XdrvMailbox.payload >= 0 ? XdrvMailbox.topic : ""),
+ (XdrvMailbox.data_len >= 0 ? XdrvMailbox.data : ""));
+ AddLog(LOG_LEVEL_INFO);
+ */
+ if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS) {
+ timeprops[XdrvMailbox.index].setPower( atof(XdrvMailbox.data), timeprop_current_time_secs );
+ }
+ snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"" D_CMND_TIMEPROP D_CMND_TIMEPROP_SETPOWER "%d\":\"%s\"}"),
+ XdrvMailbox.index, XdrvMailbox.data);
+ }
+ else {
+ serviced = false;
+ }
+ } else {
+ serviced = false;
+ }
+ return serviced;
+}
/*********************************************************************************************\
* Interface
@@ -180,6 +234,9 @@ bool Xdrv48(byte function) {
case FUNC_EVERY_SECOND:
TimepropEverySecond();
break;
+ case FUNC_COMMAND:
+ result = TimepropCommand();
+ break;
case FUNC_SET_POWER:
TimepropXdrvPower();
break;
From 02d8715d3d2534fa19b3f8e44b51c683af18ba23 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Fri, 8 Jan 2021 21:57:56 +0100
Subject: [PATCH 09/71] add ifndef to ensure "tasmota-minimal" still builds
---
tasmota/xdrv_48_timeprop.ino | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tasmota/xdrv_48_timeprop.ino b/tasmota/xdrv_48_timeprop.ino
index 10fd3e843..7bb772f08 100644
--- a/tasmota/xdrv_48_timeprop.ino
+++ b/tasmota/xdrv_48_timeprop.ino
@@ -79,7 +79,10 @@
#define TIMEPROP_RELAYS 1, 2 // which relay to control 1:8
* Publish values between 0 and 1 to the topic(s) described above
-\*********************************************************************************************/
+ *
+**/
+
+
#define D_CMND_TIMEPROP "timeprop_"
#define D_CMND_TIMEPROP_SETPOWER "setpower_" // add index no on end (0:8) and data is power 0:1
@@ -91,6 +94,7 @@ static Timeprop timeprops[TIMEPROP_NUM_OUTPUTS];
static int relayNos[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_RELAYS};
static long currentRelayStates = 0; // current actual relay states. Bit 0 first relay
+
#ifndef TIMEPROP_NUM_OUTPUTS
#define TIMEPROP_NUM_OUTPUTS 1 // how many outputs to control (with separate alogorithm for each)
#endif
@@ -178,6 +182,7 @@ bool TimepropCommand()
char command [CMDSZ];
bool serviced = true;
uint8_t ua_prefix_len = strlen(D_CMND_TIMEPROP); // to detect prefix of command
+ AddLog_P(LOG_LEVEL_ERROR, PSTR("TRP: Timeprop_Command called"));
/*
snprintf_P(log_data, sizeof(log_data), "Command called: "
"index: %d data_len: %d payload: %d topic: %s data: %s\n",
From d54ee124412670a526106506b3723635d0c0dde8 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Sat, 9 Jan 2021 18:05:54 +0100
Subject: [PATCH 10/71] add missing Response to SetPv
---
tasmota/xdrv_49_pid.ino | 1 +
1 file changed, 1 insertion(+)
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index 9d851b285..e44a7e6f1 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -266,6 +266,7 @@ void CmndSetPv(void) {
// this runs it at the next second
Pid.run_pid_now = true;
}
+ ResponseCmndNumber(atof(XdrvMailbox.data));
}
void CmndSetSp(void) {
From dee3864f871f09bdf7aaa49fd806c90bcf433338 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Sun, 10 Jan 2021 15:47:26 +0100
Subject: [PATCH 11/71] update code size metrics
---
tasmota/my_user_config.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index cad1a2e83..12f47d073 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -828,10 +828,10 @@
#define THERMOSTAT_TEMP_BAND_NO_PEAK_DET 1 // Default temperature band in thenths of degrees celsius within no peak will be detected
#define THERMOSTAT_TIME_STD_DEV_PEAK_DET_OK 10 // Default standard deviation in minutes of the oscillation periods within the peak detection is successful
-// -- PID and Timeprop ------------------------------
-//#define USE_TIMEPROP // Add support for the timeprop feature (+0k8 code)
+// -- PID and Timeprop ------------------------------ // Both together will add +12k1 code
+// #define use TIMEPROP // Add support for the timeprop feature (+9k1 code)
// For details on the configuration please see the header of tasmota/xdrv_48_timeprop.ino
-//#define USE_PID // Add suport for the PID feature (+11k1 code)
+// #define USE_PID // Add suport for the PID feature (+11k2 code)
// For details on the configuration please see the header of tasmota/xdrv_49_pid.ino
// -- End of general directives ---------------------
From 97f3a7d438d103d7ee38ef68c324dd3802940362 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Mon, 11 Jan 2021 18:42:00 +0100
Subject: [PATCH 12/71] readd TimePropCommand
---
tasmota/xdrv_48_timeprop.ino | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/tasmota/xdrv_48_timeprop.ino b/tasmota/xdrv_48_timeprop.ino
index 93a75efe9..684d6e4b3 100644
--- a/tasmota/xdrv_48_timeprop.ino
+++ b/tasmota/xdrv_48_timeprop.ino
@@ -87,6 +87,8 @@
#define D_CMND_TIMEPROP "timeprop_"
#define D_CMND_TIMEPROP_SETPOWER "setpower_" // add index no on end (0:8) and data is power 0:1
+#include "Timeprop.h"
+
enum TimepropCommands { CMND_TIMEPROP_SETPOWER };
const char kTimepropCommands[] PROGMEM = D_CMND_TIMEPROP_SETPOWER;
@@ -117,8 +119,6 @@ static long currentRelayStates = 0; // current actual relay states. Bit 0 first
#define TIMEPROP_RELAYS 1 // which relay to control 1:8
#endif
-#include "Timeprop.h"
-
struct {
Timeprop timeprops[TIMEPROP_NUM_OUTPUTS];
int relay_nos[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_RELAYS};
@@ -209,7 +209,7 @@ bool TimepropCommand()
AddLog(LOG_LEVEL_INFO);
*/
if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS) {
- timeprops[XdrvMailbox.index].setPower( atof(XdrvMailbox.data), timeprop_current_time_secs );
+ timeprops[XdrvMailbox.index].setPower( atof(XdrvMailbox.data), Tprop.current_time_secs );
}
snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("{\"" D_CMND_TIMEPROP D_CMND_TIMEPROP_SETPOWER "%d\":\"%s\"}"),
XdrvMailbox.index, XdrvMailbox.data);
@@ -239,12 +239,9 @@ bool Xdrv48(byte function) {
case FUNC_EVERY_SECOND:
TimepropEverySecond();
break;
- case FUNC_COMMAND:
- result = TimepropCommand();
- break;
- case FUNC_COMMAND:
- result = TimepropCommand();
- break;
+ case FUNC_COMMAND:
+ result = TimepropCommand();
+ break;
case FUNC_SET_POWER:
TimepropXdrvPower();
break;
@@ -252,5 +249,4 @@ bool Xdrv48(byte function) {
return result;
}
-#endif // FIRMWARE_MINIMAL
#endif // USE_TIMEPROP
From 611456327d320cb7775b1f219ebc34e960b712f2 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Mon, 11 Jan 2021 18:59:20 +0100
Subject: [PATCH 13/71] make sure code compiles with tasmota-minimal
---
tasmota/xdrv_48_timeprop.ino | 2 ++
tasmota/xdrv_49_pid.ino | 2 ++
2 files changed, 4 insertions(+)
diff --git a/tasmota/xdrv_48_timeprop.ino b/tasmota/xdrv_48_timeprop.ino
index 684d6e4b3..a885f242d 100644
--- a/tasmota/xdrv_48_timeprop.ino
+++ b/tasmota/xdrv_48_timeprop.ino
@@ -18,6 +18,7 @@
*/
#ifdef USE_TIMEPROP
+#ifndef FIRMWARE_MINIMAL
/*********************************************************************************************\
* Code to drive one or more relays in a time proportioned manner give a
* required power value.
@@ -249,4 +250,5 @@ bool Xdrv48(byte function) {
return result;
}
+#endif // FIRMWARE_MINIMAL
#endif // USE_TIMEPROP
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index e44a7e6f1..c3341b008 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -18,6 +18,7 @@
*/
#ifdef USE_PID
+#ifndef FIRMWARE_MINIMAL
/*********************************************************************************************\
* Uses the library https://github.com/colinl/process-control.git from Github
* In user_config_override.h include code as follows:
@@ -439,4 +440,5 @@ bool Xdrv49(byte function) {
}
return result;
}
+#endif //FIRMWARE_MINIMAL
#endif // USE_PID
From 06cc6406dade7946cc71da3c4a5afc2f74b6586f Mon Sep 17 00:00:00 2001
From: Marcus
Date: Mon, 11 Jan 2021 19:01:19 +0100
Subject: [PATCH 14/71] remove log entry
---
tasmota/xdrv_48_timeprop.ino | 1 -
1 file changed, 1 deletion(-)
diff --git a/tasmota/xdrv_48_timeprop.ino b/tasmota/xdrv_48_timeprop.ino
index a885f242d..5589868de 100644
--- a/tasmota/xdrv_48_timeprop.ino
+++ b/tasmota/xdrv_48_timeprop.ino
@@ -183,7 +183,6 @@ bool TimepropCommand()
char command [CMDSZ];
bool serviced = true;
uint8_t ua_prefix_len = strlen(D_CMND_TIMEPROP); // to detect prefix of command
- AddLog_P(LOG_LEVEL_ERROR, PSTR("TRP: Timeprop_Command called"));
/*
snprintf_P(log_data, sizeof(log_data), "Command called: "
"index: %d data_len: %d payload: %d topic: %s data: %s\n",
From 9b81f11f17b691b83b6287d13589924146f029be Mon Sep 17 00:00:00 2001
From: BBBits
Date: Tue, 12 Jan 2021 09:57:34 +1300
Subject: [PATCH 15/71] Resolve mDNS not restarting on wifi dn/up
also changed log prefix for mDNS from DNS: to mDN:
---
tasmota/i18n.h | 2 +-
tasmota/support_network.ino | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/tasmota/i18n.h b/tasmota/i18n.h
index 0d18f016a..3262bef09 100644
--- a/tasmota/i18n.h
+++ b/tasmota/i18n.h
@@ -680,7 +680,7 @@
#define D_LOG_KNX "KNX: "
#define D_LOG_LOG "LOG: " // Logging
#define D_LOG_MODULE "MOD: " // Module
-#define D_LOG_MDNS "DNS: " // mDNS
+#define D_LOG_MDNS "mDN: " // mDNS
#define D_LOG_MQTT "MQT: " // MQTT
#define D_LOG_OTHER "OTH: " // Other
#define D_LOG_RESULT "RSL: " // Result
diff --git a/tasmota/support_network.ino b/tasmota/support_network.ino
index 0a41b933a..b2bb73bf0 100644
--- a/tasmota/support_network.ino
+++ b/tasmota/support_network.ino
@@ -36,6 +36,7 @@ void StartMdns(void) {
// mdns_delayed_start--;
// } else {
// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
+ MDNS.end(); // close existing or MDNS.begin will fail
Mdns.begun = (uint8_t)MDNS.begin(TasmotaGlobal.hostname);
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Mdns.begun) ? D_INITIALIZED : D_FAILED);
// }
From d7e29f07037ff201f51854c8b64f13028350278d Mon Sep 17 00:00:00 2001
From: Vic
Date: Tue, 12 Jan 2021 03:27:06 +0100
Subject: [PATCH 16/71] no-library version, persistent naming option
---
tasmota/xsns_81_seesaw_soil.ino | 165 ++++++++++++++++++++++++--------
1 file changed, 126 insertions(+), 39 deletions(-)
diff --git a/tasmota/xsns_81_seesaw_soil.ino b/tasmota/xsns_81_seesaw_soil.ino
index aec9054f0..1e37d6608 100644
--- a/tasmota/xsns_81_seesaw_soil.ino
+++ b/tasmota/xsns_81_seesaw_soil.ino
@@ -20,11 +20,14 @@
#ifdef USE_I2C
#ifdef USE_SEESAW_SOIL
+
/*********************************************************************************************\
* SEESAW_SOIL - Capacitance & Temperature Sensor
*
* I2C Address: 0x36, 0x37, 0x38, 0x39
*
+ * Memory footprint: 1296 bytes flash, 64 bytes RAM
+ *
* NOTE: #define SEESAW_SOIL_PUBLISH enables immediate MQTT on soil moisture change
* otherwise the moisture value will only be emitted every TelePeriod
* #define SEESAW_SOIL_RAW enables displaying analog capacitance input in the
@@ -34,19 +37,26 @@
#define XSNS_81 81
#define XI2C_56 56 // See I2CDEVICES.md
-#include "Adafruit_seesaw.h"
+#include "Adafruit_seesaw.h" // we only use definitions, no code
-#define SEESAW_SOIL_MAX_SENSORS 4
-#define SEESAW_SOIL_START_ADDRESS 0x36
+//#define SEESAW_SOIL_RAW // enable raw readings
+//#define SEESAW_SOIL_PUBLISH // enable immediate publish
+//#define SEESAW_SOIL_PERSISTENT_NAMING // enable naming sensors by i2c address
+//#define DEBUG_SEESAW_SOIL // enable debugging
+
+#define SEESAW_SOIL_MAX_SENSORS 4
+#define SEESAW_SOIL_START_ADDRESS 0x36
const char SeeSoilName[] = "SeeSoil"; // spaces not allowed for Homeassistant integration/mqtt topics
uint8_t SeeSoilCount = 0; // global sensor count
struct SEESAW_SOIL {
- Adafruit_seesaw *ss; // instance pointer
- uint16_t capacitance;
- float temperature;
- uint8_t address;
+ uint8_t address; // i2c address
+ float moisture;
+ float temperature;
+#ifdef SEESAW_SOIL_RAW
+ uint16_t capacitance; // raw analog reading
+#endif // SEESAW_SOIL_RAW
} SeeSoil[SEESAW_SOIL_MAX_SENSORS];
// Used to convert capacitance into a moisture.
@@ -56,48 +66,122 @@ struct SEESAW_SOIL {
// So let's make a scale that converts those (apparent) facts into a percentage
#define MAX_CAPACITANCE 1020.0f // subject to calibration
#define MIN_CAPACITANCE 320 // subject to calibration
-#define CAP_TO_MOIST(c) ((max((int)(c),MIN_CAPACITANCE)-MIN_CAPACITANCE)/(MAX_CAPACITANCE-MIN_CAPACITANCE))
+#define CAP_TO_MOIST(c) ((max((int)(c),MIN_CAPACITANCE)-MIN_CAPACITANCE)/(MAX_CAPACITANCE-MIN_CAPACITANCE)*100)
-/********************************************************************************************/
+/*********************************************************************************************\
+ * i2c routines
+\*********************************************************************************************/
void SEESAW_SOILDetect(void) {
- Adafruit_seesaw *SSptr=0;
+ uint8_t buf;
+ uint32_t i, addr;
- for (uint32_t i = 0; i < SEESAW_SOIL_MAX_SENSORS; i++) {
- int addr = SEESAW_SOIL_START_ADDRESS + i;
- if (!I2cSetDevice(addr)) { continue; }
-
- if (!SSptr) { // don't have an object,
- SSptr = new Adafruit_seesaw(); // allocate one
- }
- if (SSptr->begin(addr)) {
- SeeSoil[SeeSoilCount].ss = SSptr; // save copy of pointer
- SSptr = 0; // mark that we took it
- SeeSoil[SeeSoilCount].address = addr;
- SeeSoil[SeeSoilCount].temperature = NAN;
- SeeSoil[SeeSoilCount].capacitance = 0;
- I2cSetActiveFound(SeeSoil[SeeSoilCount].address, SeeSoilName);
- SeeSoilCount++;
- }
+ for (i = 0; i < SEESAW_SOIL_MAX_SENSORS; i++) {
+ addr = SEESAW_SOIL_START_ADDRESS + i;
+ if ( ! I2cSetDevice(addr)) { continue; }
+ delay(1);
+ SEESAW_Reset(addr); // reset all seesaw MCUs at once
}
- if (SSptr) {
- delete SSptr; // used object for detection, didn't find anything so we don't need this object
+ delay(500); // give MCUs time to boot
+ for (i = 0; i < SEESAW_SOIL_MAX_SENSORS; i++) {
+ addr = SEESAW_SOIL_START_ADDRESS + i;
+ if ( ! I2cSetDevice(addr)) { continue; }
+ if ( ! SEESAW_ValidRead(addr, SEESAW_STATUS_BASE, SEESAW_STATUS_HW_ID, &buf, 1, 0)) {
+ continue;
+ }
+ if (buf != SEESAW_HW_ID_CODE) {
+#ifdef DEBUG_SEESAW_SOIL
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR("SEE: HWID mismatch ADDR=%X, ID=%X"), addr, buf);
+#endif // DEBUG_SEESAW_SOIL
+ continue;
+ }
+ SeeSoil[SeeSoilCount].address = addr;
+ SeeSoil[SeeSoilCount].temperature = NAN;
+ SeeSoil[SeeSoilCount].moisture = NAN;
+ #ifdef SEESAW_SOIL_RAW
+ SeeSoil[SeeSoilCount].capacitance = 0; // raw analog reading
+#endif // SEESAW_SOIL_RAW
+ I2cSetActiveFound(SeeSoil[SeeSoilCount].address, SeeSoilName);
+ SeeSoilCount++;
}
}
+float SEESAW_Temp(uint8_t addr) { // get temperature from seesaw at addr
+ uint8_t buf[4];
+
+ if (SEESAW_ValidRead(addr, SEESAW_STATUS_BASE, SEESAW_STATUS_TEMP, buf, 4, 1000)) {
+ int32_t ret = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
+ ((uint32_t)buf[2] << 8) | (uint32_t)buf[3];
+ return ConvertTemp((1.0 / (1UL << 16)) * ret);
+ }
+ return NAN;
+}
+
+float SEESAW_Moist(uint8_t addr) { // get moisture from seesaw at addr
+ uint8_t buf[2];
+ uint16_t ret;
+ int32_t tries = 2;
+
+ while (tries--) {
+ delay(1);
+ if (SEESAW_ValidRead(addr, SEESAW_TOUCH_BASE, SEESAW_TOUCH_CHANNEL_OFFSET, buf, 2, 3000)) {
+ ret = ((uint16_t)buf[0] << 8) | buf[1];
+#ifdef SEESAW_SOIL_RAW
+ for (int i=0; i < SeeSoilCount; i++) {
+ if (SeeSoil[i].address == addr) {
+ SeeSoil[i].capacitance = ret;
+ break;
+ }
+ }
+#endif // SEESAW_SOIL_RAW
+ if (ret != 0xFFFF) { return (float) CAP_TO_MOIST(ret); }
+ }
+ }
+ return NAN;
+}
+
+bool SEESAW_ValidRead(uint8_t addr, uint8_t regHigh, uint8_t regLow, // read from seesaw sensor
+ uint8_t *buf, uint8_t num, uint16_t delay) {
+
+ Wire.beginTransmission((uint8_t) addr);
+ Wire.write((uint8_t) regHigh);
+ Wire.write((uint8_t) regLow);
+ int err = Wire.endTransmission();
+ if (err) { return false; }
+ delayMicroseconds(delay);
+ if (num != Wire.requestFrom((uint8_t) addr, (uint8_t) num)) {
+ return false;
+ }
+ for (int i = 0; i < num; i++) {
+ buf[i] = (uint8_t) Wire.read();
+ }
+ return true;
+}
+
+bool SEESAW_Reset(uint8_t addr) { // init sensor MCU
+ Wire.beginTransmission((uint8_t) addr);
+ Wire.write((uint8_t) SEESAW_STATUS_BASE);
+ Wire.write((uint8_t) SEESAW_STATUS_SWRST);
+ return (Wire.endTransmission() == 0);
+}
+
+/*********************************************************************************************\
+ * JSON routines
+\*********************************************************************************************/
+
void SEESAW_SOILEverySecond(void) { // update sensor values and publish if changed
#ifdef SEESAW_SOIL_PUBLISH
uint32_t old_moist;
#endif // SEESAW_SOIL_PUBLISH
- for (uint32_t i = 0; i < SeeSoilCount; i++) {
- SeeSoil[i].temperature = ConvertTemp(SeeSoil[i].ss->getTemp());
+ for (int i = 0; i < SeeSoilCount; i++) {
+ SeeSoil[i].temperature = SEESAW_Temp(SeeSoil[i].address);
#ifdef SEESAW_SOIL_PUBLISH
- old_moist = uint32_t (CAP_TO_MOIST(SeeSoil[i].capacitance)*100);
+ old_moist = (uint32_t) SeeSoil[i].moisture;
#endif // SEESAW_SOIL_PUBLISH
- SeeSoil[i].capacitance = SeeSoil[i].ss->touchRead(0);
+ SeeSoil[i].moisture = SEESAW_Moist(SeeSoil[i].address);
#ifdef SEESAW_SOIL_PUBLISH
- if (uint32_t (CAP_TO_MOIST(SeeSoil[i].capacitance)*100) != old_moist) {
+ if ((uint32_t) SeeSoil[i].moisture != old_moist) {
Response_P(PSTR("{")); // send values to MQTT & rules
SEESAW_SOILJson(i);
ResponseJsonEnd();
@@ -119,20 +203,19 @@ void SEESAW_SOILShow(bool json) {
SEESAW_SOILJson(i);
if (0 == TasmotaGlobal.tele_period) {
#ifdef USE_DOMOTICZ
- DomoticzTempHumPressureSensor(SeeSoil[i].temperature, CAP_TO_MOIST(SeeSoil[i].capacitance)*100, -42.0f);
+ DomoticzTempHumPressureSensor(SeeSoil[i].temperature, SeeSoil[i].moisture, -42.0f);
#endif // USE_DOMOTICZ
#ifdef USE_KNX
KnxSensor(KNX_TEMPERATURE, SeeSoil[i].temperature);
- KnxSensor(KNX_HUMIDITY, CAP_TO_MOIST(SeeSoil[i].capacitance) * 100);
+ KnxSensor(KNX_HUMIDITY, SeeSoil[i].moisture);
#endif // USE_KNX
}
#ifdef USE_WEBSERVER
} else {
#ifdef SEESAW_SOIL_RAW
- WSContentSend_PD(HTTP_SNS_ANALOG, sensor_name, 0, SeeSoil[i].capacitance); // dump raw value
+ WSContentSend_PD(HTTP_SNS_ANALOG, sensor_name, 0, SeeSoil[i].capacitance);
#endif // SEESAW_SOIL_RAW
- WSContentSend_PD(HTTP_SNS_MOISTURE, sensor_name,
- uint32_t (CAP_TO_MOIST(SeeSoil[i].capacitance)*100)); // web page formats as integer (%d) percent
+ WSContentSend_PD(HTTP_SNS_MOISTURE, sensor_name, (uint32_t) SeeSoil[i].moisture);
WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, temperature, TempUnit());
#endif // USE_WEBSERVER
}
@@ -146,17 +229,21 @@ void SEESAW_SOILJson(int no) { // common json
SEESAW_SOILName(no, sensor_name, sizeof(sensor_name));
dtostrfd(SeeSoil[no].temperature, Settings.flag2.temperature_resolution, temperature);
ResponseAppend_P(PSTR ("\"%s\":{\"" D_JSON_ID "\":\"%02X\",\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_MOISTURE "\":%u}"),
- sensor_name, SeeSoil[no].address, temperature, uint32_t (CAP_TO_MOIST(SeeSoil[no].capacitance)*100));
+ sensor_name, SeeSoil[no].address, temperature, (uint32_t) SeeSoil[no].moisture);
}
void SEESAW_SOILName(int no, char *name, int len) // generates a sensor name
{
+#ifdef SEESAW_SOIL_PERSISTENT_NAMING
+ snprintf_P(name, len, PSTR("%s%c%02X"), SeeSoilName, IndexSeparator(), SeeSoil[no].address);
+#else
if (SeeSoilCount > 1) {
snprintf_P(name, len, PSTR("%s%c%u"), SeeSoilName, IndexSeparator(), no + 1);
}
else {
strlcpy(name, SeeSoilName, len);
}
+#endif // SEESAW_SOIL_PERSISTENT_NAMING
}
/*********************************************************************************************\
From 0d81ffe30b21f678ff1d31febe3bbd35bc2784ca Mon Sep 17 00:00:00 2001
From: JohnG
Date: Mon, 11 Jan 2021 20:12:46 -0800
Subject: [PATCH 17/71] Added support for multiple arguments to a subroutine.
---
tasmota/xdrv_10_scripter.ino | 94 +++++++++++++++++++-----------------
1 file changed, 50 insertions(+), 44 deletions(-)
diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino
index 8f1a3e2be..198e58077 100755
--- a/tasmota/xdrv_10_scripter.ino
+++ b/tasmota/xdrv_10_scripter.ino
@@ -4550,53 +4550,59 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonParserObject *jo) {
if (*ctype=='#') {
// check for parameter
ctype += tlen;
- if (*ctype=='(' && *(lp+tlen)=='(') {
- float fparam;
- numeric = 1;
- glob_script_mem.glob_error = 0;
- GetNumericArgument((char*)ctype, OPER_EQU, &fparam, 0);
- if (glob_script_mem.glob_error==1) {
- // was string, not number
- numeric = 0;
- // get the string
- GetStringArgument((char*)ctype + 1, OPER_EQU, cmpstr, 0);
- }
- lp += tlen;
- if (*lp=='(') {
- // fetch destination
- lp++;
- lp = isvar(lp, &vtype, &ind, 0, 0, 0);
- if (vtype!=VAR_NV) {
- // found variable as result
- uint8_t index = glob_script_mem.type[ind.index].index;
- if ((vtype&STYPE)==0) {
- // numeric result
- dfvar = &glob_script_mem.fvars[index];
- if (numeric) {
- *dfvar = fparam;
- } else {
- // mismatch
- *dfvar = CharToFloat(cmpstr);
- }
- } else {
- // string result
- sindex = index;
- if (!numeric) {
- strlcpy(glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize), cmpstr, glob_script_mem.max_ssize);
- } else {
- // mismatch
- dtostrfd(fparam, 6, glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize));
- }
+ char nxttok = '(';
+ char *argptr = ctype+tlen;
+
+ lp += tlen;
+ do {
+ if (*ctype==nxttok && *lp==nxttok) {
+ float fparam;
+ numeric = 1;
+ glob_script_mem.glob_error = 0;
+ argptr = GetNumericArgument((char*)ctype + 1, OPER_EQU, &fparam, 0);
+ if (glob_script_mem.glob_error==1) {
+ // was string, not number
+ numeric = 0;
+ // get the string
+ argptr = GetStringArgument((char*)ctype + 1, OPER_EQU, cmpstr, 0);
+ }
+ if (*lp==nxttok) {
+ // fetch destination
+ lp++;
+ lp = isvar(lp, &vtype, &ind, 0, 0, 0);
+ if (vtype!=VAR_NV) {
+ // found variable as result
+ uint8_t index = glob_script_mem.type[ind.index].index;
+ if ((vtype&STYPE)==0) {
+ // numeric result
+ dfvar = &glob_script_mem.fvars[index];
+ if (numeric) {
+ *dfvar = fparam;
+ } else {
+ // mismatch
+ *dfvar = CharToFloat(cmpstr);
+ }
+ } else {
+ // string result
+ sindex = index;
+ if (!numeric) {
+ strlcpy(glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize), cmpstr, glob_script_mem.max_ssize);
+ } else {
+ // mismatch
+ dtostrfd(fparam, 6, glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize));
+ }
+ }
}
}
+ } else {
+ if (*ctype==nxttok || (*lp!=SCRIPT_EOL && *lp!='?')) {
+ // revert
+ section = 0;
+ }
}
- } else {
- lp += tlen;
- if (*ctype=='(' || (*lp!=SCRIPT_EOL && *lp!='?')) {
- // revert
- section = 0;
- }
- }
+ nxttok = ' ';
+ ctype = argptr;
+ } while (*lp==' ' && (section == 1) );
}
}
}
From e56a08f4de7a8258a4736a5de94fb6505611c368 Mon Sep 17 00:00:00 2001
From: Marcus
Date: Tue, 12 Jan 2021 09:00:17 +0100
Subject: [PATCH 18/71] Change Response to Float, where floats are stored
---
tasmota/xdrv_49_pid.ino | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index c3341b008..2773137a5 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -267,27 +267,27 @@ void CmndSetPv(void) {
// this runs it at the next second
Pid.run_pid_now = true;
}
- ResponseCmndNumber(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data));
}
void CmndSetSp(void) {
Pid.pid.setSp(atof(XdrvMailbox.data));
- ResponseCmndNumber(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data));
}
void CmndSetPb(void) {
Pid.pid.setPb(atof(XdrvMailbox.data));
- ResponseCmndNumber(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data));
}
void CmndSetTi(void) {
Pid.pid.setTi(atof(XdrvMailbox.data));
- ResponseCmndNumber(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data));
}
void CmndSetTd(void) {
Pid.pid.setTd(atof(XdrvMailbox.data));
- ResponseCmndNumber(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data));
}
void CmndSetInitialInt(void) {
@@ -297,7 +297,7 @@ void CmndSetInitialInt(void) {
void CmndSetDSmooth(void) {
Pid.pid.setDSmooth(atof(XdrvMailbox.data));
- ResponseCmndNumber(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data));
}
void CmndSetAuto(void) {
@@ -307,7 +307,7 @@ void CmndSetAuto(void) {
void CmndSetManualPower(void) {
Pid.pid.setManualPower(atof(XdrvMailbox.data));
- ResponseCmndNumber(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data));
}
void CmndSetMaxInterval(void) {
From e63b3d9ac9bcafda5764eba3725bb575dd8e895b Mon Sep 17 00:00:00 2001
From: Marcus
Date: Tue, 12 Jan 2021 09:14:19 +0100
Subject: [PATCH 19/71] add number of digits to ResponseCmndFloat
---
tasmota/xdrv_49_pid.ino | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tasmota/xdrv_49_pid.ino b/tasmota/xdrv_49_pid.ino
index 2773137a5..15097106b 100644
--- a/tasmota/xdrv_49_pid.ino
+++ b/tasmota/xdrv_49_pid.ino
@@ -267,27 +267,27 @@ void CmndSetPv(void) {
// this runs it at the next second
Pid.run_pid_now = true;
}
- ResponseCmndFloat(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data), 1);
}
void CmndSetSp(void) {
Pid.pid.setSp(atof(XdrvMailbox.data));
- ResponseCmndFloat(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data), 1);
}
void CmndSetPb(void) {
Pid.pid.setPb(atof(XdrvMailbox.data));
- ResponseCmndFloat(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data), 1);
}
void CmndSetTi(void) {
Pid.pid.setTi(atof(XdrvMailbox.data));
- ResponseCmndFloat(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data), 1);
}
void CmndSetTd(void) {
Pid.pid.setTd(atof(XdrvMailbox.data));
- ResponseCmndFloat(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data), 1);
}
void CmndSetInitialInt(void) {
@@ -297,7 +297,7 @@ void CmndSetInitialInt(void) {
void CmndSetDSmooth(void) {
Pid.pid.setDSmooth(atof(XdrvMailbox.data));
- ResponseCmndFloat(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data), 1);
}
void CmndSetAuto(void) {
@@ -307,7 +307,7 @@ void CmndSetAuto(void) {
void CmndSetManualPower(void) {
Pid.pid.setManualPower(atof(XdrvMailbox.data));
- ResponseCmndFloat(atof(XdrvMailbox.data));
+ ResponseCmndFloat(atof(XdrvMailbox.data), 1);
}
void CmndSetMaxInterval(void) {
From 43e5a2c19e913eb0ae0532eac0c70f8883f40678 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Tue, 12 Jan 2021 09:20:56 +0100
Subject: [PATCH 20/71] Update API doc
---
API.md | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/API.md b/API.md
index 7bb77735b..b631172ed 100644
--- a/API.md
+++ b/API.md
@@ -14,8 +14,8 @@ Callback Id | Bool | xdrv | xsns | xnrg | xlgt | Description
----------------------------|------|------|------|------|------|----------------------------------
FUNC_SETTINGS_OVERRIDE | | x | | | | Override start-up settings
FUNC_PIN_STATE | x | 1 | 2 | | | At GPIO configuration
-FUNC_MODULE_INIT | x | 1 | | | 2 | Init module specific parameters
-FUNC_PRE_INIT | | 1 | | 2 | | Once GPIO have been established
+FUNC_MODULE_INIT | x | 3 | 1 | | 2 | Init module specific parameters
+FUNC_PRE_INIT | | 1 | 3 | 2 | | Once GPIO have been established
FUNC_INIT | | 1 | 3 | 2 | | At end of initialisation
FUNC_LOOP | | 1 | 2 | | | In main loop
FUNC_EVERY_50_MSECOND | | 1 | 2 | | |
@@ -34,7 +34,7 @@ FUNC_COMMAND_SENSOR | x | | x | | | When command Se
FUNC_MQTT_SUBSCRIBE | | x | | | | At end of MQTT subscriptions
FUNC_MQTT_INIT | | x | | | | Once at end of MQTT connection
FUNC_MQTT_DATA | x | x | | | | Before decoding command
-FUNC_SET_POWER | | x | | | | Before setting relays
+FUNC_SET_POWER | | 1 | 2 | | | Before setting relays
FUNC_SET_DEVICE_POWER | x | x | | | | Set relay
FUNC_SHOW_SENSOR | | x | | | | When FUNC_JSON_APPEND completes
FUNC_ANY_KEY | | x | | | |
@@ -49,6 +49,8 @@ FUNC_WEB_ADD_MAIN_BUTTON | | 1 | 2 | | | Add a main butt
FUNC_WEB_ADD_HANDLER | | 1 | 2 | | | Add a webserver handler
FUNC_SET_CHANNELS | | 2 | | | 1 |
FUNC_SET_SCHEME | | | | | x |
+FUNC_HOTPLUG_SCAN | | | x | | |
+FUNC_DEVICE_GROUP_ITEM | | x | | | |
The numbers represent the sequence of execution
@@ -89,12 +91,15 @@ CFG: Loaded from flash at FB, Count 1581
xdrv - FUNC_SETTINGS_OVERRIDE
xdrv - FUNC_PIN_STATE
xsns - FUNC_PIN_STATE
+xsns - FUNC_MODULE_INIT
xdrv - FUNC_MODULE_INIT
xlgt - FUNC_MODULE_INIT
xdrv - FUNC_PRE_INIT
xnrg - FUNC_PRE_INIT
+xsns - FUNC_PRE_INIT
SRC: Restart
xdrv - FUNC_SET_POWER
+xsns - FUNC_SET_POWER
xlgt - FUNC_SET_CHANNELS
xdrv - FUNC_SET_DEVICE_POWER
Project tasmota Wemos 2 Version 7.0.0.3(tasmota)-STAGE
From e7c96fbb7897ffd8b11d7213e8793eabef91b0e5 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 12 Jan 2021 09:44:18 +0100
Subject: [PATCH 21/71] Support for 2M and 4MB builds
---
platformio_override_sample.ini | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index 3d624c30f..3d95545ad 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -48,6 +48,17 @@ build_flags = ${core.build_flags}
; -DDEBUG_TASMOTA_DRIVER
; -DDEBUG_TASMOTA_SENSOR
+; *** CAUTION *** This setting is ONLY possible since 12.01.2021 with development version !!!
+; *** Enable only if you exactly know what are you doing
+; *** If you try with earlier builds a serial erase and flash is probably needed
+;
+; Build variant 1MB = 1MB firmware no filesystem (default)
+;board_build.ldscript = eagle.flash.1m.ld
+; Build variant 2MB = 1MB firmware, 1MB filesystem (ZigbeeBridge, most Shelly devices)
+;board_build.ldscript = eagle.flash.2m1m.ld
+; Build variant 4MB = 1MB firmware, 3MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW)
+;board_build.ldscript = eagle.flash.4m3m.ld
+
; set CPU frequency to 80MHz (default) or 160MHz
;board_build.f_cpu = 160000000L
From c1d6d30cabd32e390c7431756a0a6700766cbb70 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 12 Jan 2021 10:27:07 +0100
Subject: [PATCH 22/71] Update I2CDEVICES.md
---
I2CDEVICES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/I2CDEVICES.md b/I2CDEVICES.md
index 22616d670..301b48111 100644
--- a/I2CDEVICES.md
+++ b/I2CDEVICES.md
@@ -75,7 +75,7 @@ Index | Define | Driver | Device | Address(es) | Description
50 | USE_VEML7700 | xsns_71 | VEML7700 | 0x10 | Ambient light intensity sensor
51 | USE_MCP9808 | xsns_72 | MCP9808 | 0x18 - 0x1F | Temperature sensor
52 | USE_HP303B | xsns_73 | HP303B | 0x76 - 0x77 | Pressure and temperature sensor
- 53 | USE_MLX90640 | xdrv_84 | MLX90640 | 0x33 | IR array temperature sensor
+ 53 | USE_MLX90640 | xdrv_43 | MLX90640 | 0x33 | IR array temperature sensor
54 | USE_VL53L1X | xsns_77 | VL53L1X | 0x29 | Time-of-flight (ToF) distance sensor
55 | USE_EZOPH | xsns_78 | EZOPH | 0x61 - 0x70 | pH sensor
55 | USE_EZOORP | xsns_78 | EZOORP | 0x61 - 0x70 | ORP sensor
From 120ba5cac2fd840ac2bde382aec95f0bcd727e15 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 12 Jan 2021 10:51:46 +0100
Subject: [PATCH 23/71] Add extra recovery option when linker changed
---
tasmota/settings.ino | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tasmota/settings.ino b/tasmota/settings.ino
index 518eb03d2..607cbdb44 100644
--- a/tasmota/settings.ino
+++ b/tasmota/settings.ino
@@ -205,14 +205,16 @@ uint32_t SETTINGS_LOCATION = FLASH_EEPROM_START;
#endif // ESP32
-const uint8_t CFG_ROTATES = 7; // Number of flash sectors used (handles uploads)
+const uint8_t CFG_ROTATES = 7; // Number of flash sectors used (handles uploads)
uint32_t settings_location = FLASH_EEPROM_START;
uint32_t settings_crc32 = 0;
uint8_t *settings_buffer = nullptr;
void SettingsInit(void) {
- if (SETTINGS_LOCATION > 0xFA) { SETTINGS_LOCATION = 0xFA; } // Skip empty partition part
+ if (SETTINGS_LOCATION > 0xFA) {
+ SETTINGS_LOCATION = 0xFD; // Skip empty partition part
+ }
}
/********************************************************************************************/
From b62f0ff3cf312d8ea874a0d014429129bc04ffd7 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 12 Jan 2021 11:29:13 +0100
Subject: [PATCH 24/71] added eagle.flash.4m2m.ld
---
platformio_override_sample.ini | 2 ++
1 file changed, 2 insertions(+)
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index 3d95545ad..eb550c695 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -58,6 +58,8 @@ build_flags = ${core.build_flags}
;board_build.ldscript = eagle.flash.2m1m.ld
; Build variant 4MB = 1MB firmware, 3MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW)
;board_build.ldscript = eagle.flash.4m3m.ld
+; Build variant 4MB = 1MB firmware, 1MB OTA, 2MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW)
+;board_build.ldscript = eagle.flash.4m2m.ld
; set CPU frequency to 80MHz (default) or 160MHz
;board_build.f_cpu = 160000000L
From ad55e49ed266648b620241a56c916b36da7b2a27 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 12 Jan 2021 12:05:20 +0100
Subject: [PATCH 25/71] Use eagle.flash.2m256.ld for zbbridge
---
platformio_tasmota_env.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini
index f24794b68..442e33b48 100644
--- a/platformio_tasmota_env.ini
+++ b/platformio_tasmota_env.ini
@@ -64,6 +64,7 @@ build_flags = ${common.build_flags} ${irremoteesp_full.build_flags}
[env:tasmota-zbbridge]
build_flags = ${common.build_flags} -DFIRMWARE_ZBBRIDGE
+board_build.ldscript = eagle.flash.2m256.ld
board_build.f_cpu = 160000000L
lib_extra_dirs = lib/lib_ssl
From 4ff1c8daa3fe70cbe7d4af642db4a349ec045abf Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 12 Jan 2021 12:18:32 +0100
Subject: [PATCH 26/71] Update platformio_override_sample.ini
---
platformio_override_sample.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index eb550c695..814132fae 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -54,7 +54,7 @@ build_flags = ${core.build_flags}
;
; Build variant 1MB = 1MB firmware no filesystem (default)
;board_build.ldscript = eagle.flash.1m.ld
-; Build variant 2MB = 1MB firmware, 1MB filesystem (ZigbeeBridge, most Shelly devices)
+; Build variant 2MB = 1MB firmware, 1MB filesystem (most Shelly devices)
;board_build.ldscript = eagle.flash.2m1m.ld
; Build variant 4MB = 1MB firmware, 3MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW)
;board_build.ldscript = eagle.flash.4m3m.ld
From 15598d71a902bc0b62331408bdd1facf6571c2ea Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 12 Jan 2021 14:54:12 +0100
Subject: [PATCH 27/71] Fix reset 5 and 6 when filesystem in use
---
tasmota/settings.ino | 110 +++++++++++++++++-------------------
tasmota/support_esp32.ino | 2 +-
tasmota/support_esptool.ino | 2 +
tasmota/support_tasmota.ino | 2 +-
4 files changed, 56 insertions(+), 60 deletions(-)
diff --git a/tasmota/settings.ino b/tasmota/settings.ino
index 607cbdb44..2f9bad000 100644
--- a/tasmota/settings.ino
+++ b/tasmota/settings.ino
@@ -154,19 +154,20 @@ bool RtcRebootValid(void)
* 0x000xxxxx - Unzipped binary code end
* 0x000x1000 - First page used by Core OTA
* ::::
- * 0x000F2FFF
+ * 0x000F2FFF 0x000F5FFF 0x000F5FFF
******************************************************************************
* Next 32k is overwritten by OTA
- * 0x000F3000 - 4k Tasmota Quick Power Cycle counter (SETTINGS_LOCATION - CFG_ROTATES) - First four bytes only
- * 0x000F3FFF
- * 0x000F4000 - 4k First Tasmota rotating settings page
+ * 0x000F3000 0x000F6000 0x000F6000 - 4k Tasmota Quick Power Cycle counter (SETTINGS_LOCATION - CFG_ROTATES) - First four bytes only
+ * 0x000F3FFF 0x000F6FFF 0x000F6FFF
+ * 0x000F4000 0x000F7000 0x000F7000 - 4k First Tasmota rotating settings page
* ::::
- * 0x000FA000 - 4k Last Tasmota rotating settings page = Last page used by Core OTA (SETTINGS_LOCATION)
- * 0x000FAFFF
+ * 0x000FA000 0x000FD000 0x000FD000 - 4k Last Tasmota rotating settings page = Last page used by Core OTA (SETTINGS_LOCATION)
+ * 0x000FAFFF 0x000FDFFF 0x000FDFFF
******************************************************************************
- * 0x000FB000 0x000FB000 - 15k9 Not used
+ * 0x000FE000 0x000FE000 - 3k9 Not used
* 0x000FEFF0 0x000FEFF0 - 4k1 Empty
* 0x000FFFFF 0x000FFFFF
+ *
* 0x000FB000 0x00100000 0x00100000 - 0k, 980k or 2980k Core FS start (LittleFS)
* 0x000FB000 0x001FA000 0x003FA000 - 0k, 980k or 2980k Core FS end (LittleFS)
* 0x001FAFFF 0x003FAFFF
@@ -189,7 +190,8 @@ extern "C" {
#ifdef ESP8266
extern "C" uint32_t _FS_start; // 1M = 0x402fb000, 2M = 0x40300000, 4M = 0x40300000
-uint32_t SETTINGS_LOCATION = (((uint32_t)&_FS_start - 0x40200000) / SPI_FLASH_SEC_SIZE) -1; // 0xFA, 0xFF or 0xFF
+const uint32_t FLASH_FS_START = (((uint32_t)&_FS_start - 0x40200000) / SPI_FLASH_SEC_SIZE);
+uint32_t SETTINGS_LOCATION = FLASH_FS_START -1; // 0xFA, 0x0FF or 0x0FF
// From libraries/EEPROM/EEPROM.cpp EEPROMClass
extern "C" uint32_t _EEPROM_start; // 1M = 0x402FB000, 2M = 0x403FB000, 4M = 0x405FB000
@@ -213,7 +215,7 @@ uint8_t *settings_buffer = nullptr;
void SettingsInit(void) {
if (SETTINGS_LOCATION > 0xFA) {
- SETTINGS_LOCATION = 0xFD; // Skip empty partition part
+ SETTINGS_LOCATION = 0xFD; // Skip empty partition part and keep in first 1M
}
}
@@ -536,6 +538,9 @@ void SettingsSave(uint8_t rotate)
Settings.cfg_crc32 = GetSettingsCrc32();
#ifdef ESP8266
+#ifdef USE_UFILESYS
+ TfsSaveFile(TASM_FILE_SETTINGS, (const uint8_t*)&Settings, sizeof(Settings));
+#endif
if (ESP.flashEraseSector(settings_location)) {
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
}
@@ -561,12 +566,18 @@ void SettingsSave(uint8_t rotate)
void SettingsLoad(void) {
#ifdef ESP8266
+#ifdef USE_UFILESYS
+ if (TfsLoadFile(TASM_FILE_SETTINGS, (uint8_t*)&Settings, sizeof(Settings))) {
+ settings_location = 1;
+ AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded from File, " D_COUNT " %lu"), Settings.save_flag);
+ } else {
+#endif
// Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate
// Activated with version 8.4.0.2 - Fails to read any config before version 6.6.0.11
settings_location = 0;
uint32_t save_flag = 0;
uint32_t flash_location = FLASH_EEPROM_START;
- for (uint32_t i = 0; i < CFG_ROTATES; i++) { // Read all config pages in search of valid and latest
+ for (uint32_t i = 0; i <= CFG_ROTATES; i++) { // Read all config pages in search of valid and latest
if (1 == i) { flash_location = SETTINGS_LOCATION; }
ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
if ((Settings.cfg_crc32 != 0xFFFFFFFF) && (Settings.cfg_crc32 != 0x00000000) && (Settings.cfg_crc32 == GetSettingsCrc32())) {
@@ -585,9 +596,13 @@ void SettingsLoad(void) {
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
}
+#ifdef USE_UFILESYS
+ }
+#endif
#endif // ESP8266
#ifdef ESP32
uint32_t source = SettingsRead(&Settings, sizeof(Settings));
+ if (source) { settings_location = 1; }
AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded from %s, " D_COUNT " %lu"), (source)?"File":"Nvm", Settings.save_flag);
#endif // ESP32
@@ -606,25 +621,6 @@ uint32_t CfgTime(void) {
return Settings.cfg_timestamp;
}
-void EspErase(uint32_t start_sector, uint32_t end_sector)
-{
- bool serial_output = (LOG_LEVEL_DEBUG_MORE <= TasmotaGlobal.seriallog_level);
- for (uint32_t sector = start_sector; sector < end_sector; sector++) {
-
- bool result = ESP.flashEraseSector(sector); // Arduino core - erases flash as seen by SDK
-// bool result = !SPIEraseSector(sector); // SDK - erases flash as seen by SDK
-// bool result = EsptoolEraseSector(sector); // Esptool - erases flash completely (slow)
-
- if (serial_output) {
- Serial.printf_P(PSTR(D_LOG_APPLICATION D_ERASED_SECTOR " %d %s\n"), sector, (result) ? D_OK : D_ERROR);
- delay(10);
- } else {
- yield();
- }
- OsWatchLoop();
- }
-}
-
#ifdef ESP8266
void SettingsErase(uint8_t type)
{
@@ -637,54 +633,52 @@ void SettingsErase(uint8_t type)
The default erase function is EspTool (EsptoolErase)
- 0 = Erase from program end until end of flash as seen by SDK
- 1 = Erase 16k SDK parameter area near end of flash as seen by SDK (0x0xFCxxx - 0x0xFFFFF) solving possible wifi errors
- 2 = Erase Tasmota parameter area (0x0xF3xxx - 0x0xFBFFF)
+ 0 = Erase from program end until end of flash as seen by SDK including optional filesystem
+ 1 = Erase 16k SDK parameter area near end of flash as seen by SDK (0x0XFCxxx - 0x0XFFFFF) solving possible wifi errors
+ 2 = Erase from program end until end of flash as seen by SDK excluding optional filesystem
3 = Erase Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
4 = Erase SDK parameter area used for wifi calibration (0x0FCxxx - 0x0FCFFF)
*/
#ifndef FIRMWARE_MINIMAL
+ // Reset 2 = Erase all flash from program end to end of physical flash
uint32_t _sectorStart = (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 1;
uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE; // Flash size as reported by hardware
- if (1 == type) {
+ if (1 == type) { // Reset 3 = SDK parameter area
// source Esp.cpp and core_esp8266_phy.cpp
- _sectorStart = (ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE) - 4; // SDK parameter area
- }
- else if (2 == type) {
- _sectorStart = SETTINGS_LOCATION - CFG_ROTATES; // Tasmota parameter area (0x0F3xxx - 0x0FAFFF)
- _sectorEnd = SETTINGS_LOCATION;
- }
- else if (3 == type) {
- _sectorStart = SETTINGS_LOCATION - CFG_ROTATES; // Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
- _sectorEnd = ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE; // Flash size as seen by SDK
- }
- else if (4 == type) {
-// _sectorStart = (ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE) - 4; // SDK phy area and Core calibration sector (0x0FC000)
- _sectorStart = FLASH_EEPROM_START +1; // SDK phy area and Core calibration sector (0x0FC000)
- _sectorEnd = _sectorStart +1; // SDK end of phy area and Core calibration sector (0x0FCFFF)
+ _sectorStart = (ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE) - 4;
}
+ else if (2 == type) { // Reset 5, 6 = Erase all flash from program end to end of physical flash but skip filesystem
/*
- else if (5 == type) {
- _sectorStart = (ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE) -4; // SDK phy area and Core calibration sector (0xxFC000)
- _sectorEnd = _sectorStart +1; // SDK end of phy area and Core calibration sector (0xxFCFFF)
- }
+#ifdef USE_UFILESYS
+ TfsDeleteFile(TASM_FILE_SETTINGS); // Not needed as it is recreated by set defaults before restart
+#endif
*/
- else {
- return;
+ EsptoolErase(_sectorStart, FLASH_FS_START);
+ _sectorStart = FLASH_EEPROM_START;
+ _sectorEnd = ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE; // Flash size as seen by SDK
+ }
+ else if (3 == type) { // QPC Reached = QPC and Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
+#ifdef USE_UFILESYS
+ TfsDeleteFile(TASM_FILE_SETTINGS);
+#endif
+ EsptoolErase(SETTINGS_LOCATION - CFG_ROTATES, SETTINGS_LOCATION +1);
+ _sectorStart = FLASH_EEPROM_START;
+ _sectorEnd = ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE; // Flash size as seen by SDK
+ }
+ else if (4 == type) { // WIFI_FORCE_RF_CAL_ERASE = SDK wifi calibration
+ _sectorStart = FLASH_EEPROM_START +1; // SDK phy area and Core calibration sector (0x0XFC000)
+ _sectorEnd = _sectorStart +1; // SDK end of phy area and Core calibration sector (0x0XFCFFF)
}
- AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " from 0x%08X to 0x%08X"), _sectorStart * SPI_FLASH_SEC_SIZE, (_sectorEnd * SPI_FLASH_SEC_SIZE) -1);
-
-// EspErase(_sectorStart, _sectorEnd); // Arduino core and SDK - erases flash as seen by SDK
- EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely
+ EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely
#endif // FIRMWARE_MINIMAL
}
#endif // ESP8266
void SettingsSdkErase(void)
{
- WiFi.disconnect(false); // Delete SDK wifi config
+ WiFi.disconnect(false); // Delete SDK wifi config
SettingsErase(1);
delay(1000);
}
diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino
index 40ef5fe43..d56040b86 100644
--- a/tasmota/support_esp32.ino
+++ b/tasmota/support_esp32.ino
@@ -138,7 +138,7 @@ int32_t NvmErase(const char *sNvsName) {
void SettingsErase(uint8_t type) {
// SDK and Tasmota data is held in default NVS partition
- // Tasmota data is held also in file /settings on default filesystem
+ // Tasmota data is held also in file /.settings on default filesystem
// cal_data - SDK PHY calibration data as documented in esp_phy_init.h
// qpc - Tasmota Quick Power Cycle state
// main - Tasmota Settings data
diff --git a/tasmota/support_esptool.ino b/tasmota/support_esptool.ino
index f100a4706..6551c7912 100644
--- a/tasmota/support_esptool.ino
+++ b/tasmota/support_esptool.ino
@@ -95,6 +95,8 @@ bool EsptoolEraseSector(uint32_t sector)
void EsptoolErase(uint32_t start_sector, uint32_t end_sector)
{
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " from 0x%06X to 0x%06X"), start_sector * SPI_FLASH_SEC_SIZE, (end_sector * SPI_FLASH_SEC_SIZE) -1);
+
int next_erase_sector = start_sector;
int remaining_erase_sector = end_sector - start_sector;
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index 08205d23d..597435e40 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -1134,7 +1134,7 @@ void Every250mSeconds(void)
// Backup mqtt host, port, client, username and password
// }
if ((215 == TasmotaGlobal.restart_flag) || (216 == TasmotaGlobal.restart_flag)) {
- SettingsErase(0); // Erase all flash from program end to end of physical flash
+ SettingsErase(2); // Erase all flash from program end to end of physical excluding optional filesystem
}
SettingsDefault();
// Restore current SSIDs and Passwords
From 08033444c5ac1bd8624f91e41cfbffbc140f7d06 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 12 Jan 2021 15:03:06 +0100
Subject: [PATCH 28/71] Fix filetime
---
tasmota/support_rtc.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino
index e9afa4597..990e78666 100644
--- a/tasmota/support_rtc.ino
+++ b/tasmota/support_rtc.ino
@@ -455,7 +455,7 @@ void RtcSecond(void)
Rtc.midnight_now = true;
}
-#ifdef ESP32
+//#ifdef ESP32
if (mutex) { // Time is just synced and is valid
// Sync RTOS time to be used by SD Card time stamps
struct timeval tv;
@@ -463,7 +463,7 @@ void RtcSecond(void)
tv.tv_usec = 0;
settimeofday(&tv, nullptr);
}
-#endif // ESP32
+//#endif // ESP32
}
From c494c89a1a9cff9e7df9e71f12c2d50ad20a7d91 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 12 Jan 2021 15:13:42 +0100
Subject: [PATCH 29/71] Update support_rtc.ino
---
tasmota/support_rtc.ino | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino
index 990e78666..08f7cfc3d 100644
--- a/tasmota/support_rtc.ino
+++ b/tasmota/support_rtc.ino
@@ -455,16 +455,13 @@ void RtcSecond(void)
Rtc.midnight_now = true;
}
-//#ifdef ESP32
if (mutex) { // Time is just synced and is valid
- // Sync RTOS time to be used by SD Card time stamps
+ // Sync Core/RTOS time to be used by file system time stamps
struct timeval tv;
tv.tv_sec = Rtc.local_time;
tv.tv_usec = 0;
settimeofday(&tv, nullptr);
}
-//#endif // ESP32
-
}
RtcTime.year += 1970;
From 4181a884ebe779ae49f4b6e86f0aface80762edf Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 12 Jan 2021 15:33:15 +0100
Subject: [PATCH 30/71] support littlefs with PlatformIO
---
platformio.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio.ini b/platformio.ini
index c03175200..e76901e33 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -66,6 +66,7 @@ default_envs = ${build_envs.default_envs}
[common]
framework = arduino
board = esp01_1m
+board_build.filesystem = littlefs
board_build.flash_mode = dout
board_build.ldscript = eagle.flash.1m.ld
From 65ba49e59465399e62bb05eb5a61effd6fc80854 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 12 Jan 2021 15:35:08 +0100
Subject: [PATCH 31/71] add littlefs
---
platformio_tasmota_env.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini
index 442e33b48..ce05c138f 100644
--- a/platformio_tasmota_env.ini
+++ b/platformio_tasmota_env.ini
@@ -3,6 +3,7 @@ platform = ${common.platform}
platform_packages = ${common.platform_packages}
framework = ${common.framework}
board = ${common.board}
+board_build.filesystem = ${common.board_build.filesystem}
board_build.ldscript = ${common.board_build.ldscript}
board_build.flash_mode = ${common.board_build.flash_mode}
board_build.f_flash = ${common.board_build.f_flash}
From a376ff6e532e39c9a2d2518e7fad27aa4c5de74d Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 12 Jan 2021 15:36:27 +0100
Subject: [PATCH 32/71] add littlefs
---
platformio_tasmota32.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini
index 7234d9417..79c56eb96 100644
--- a/platformio_tasmota32.ini
+++ b/platformio_tasmota32.ini
@@ -47,6 +47,7 @@ platform_packages = ${core32.platform_packages}
build_unflags = ${core32.build_unflags}
build_flags = ${core32.build_flags}
board = esp32dev
+board_build.filesystem = ${common.board_build.filesystem}
board_build.ldscript = esp32_out.ld
board_build.partitions = esp32_partition_app1984k_spiffs64k.csv
board_build.flash_mode = ${common.board_build.flash_mode}
From 9c5e6acdc146257f08a4b66f86b684ce5b3ac092 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 12 Jan 2021 15:44:40 +0100
Subject: [PATCH 33/71] Tasmota supported linker files
Lets decide to currently only support these.
---
platformio_override_sample.ini | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index 814132fae..344faeea3 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -54,12 +54,12 @@ build_flags = ${core.build_flags}
;
; Build variant 1MB = 1MB firmware no filesystem (default)
;board_build.ldscript = eagle.flash.1m.ld
-; Build variant 2MB = 1MB firmware, 1MB filesystem (most Shelly devices)
-;board_build.ldscript = eagle.flash.2m1m.ld
-; Build variant 4MB = 1MB firmware, 3MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW)
-;board_build.ldscript = eagle.flash.4m3m.ld
-; Build variant 4MB = 1MB firmware, 1MB OTA, 2MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW)
+; Build variant 2MB = 1MB firmware, +744k OTA, 256k filesystem (Zigbee Bridge, most Shelly devices)
+;board_build.ldscript = eagle.flash.2m256.ld
+; Build variant 4MB = 1MB firmware, +1MB OTA, 2MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW)
;board_build.ldscript = eagle.flash.4m2m.ld
+; Build variant 16MB = 1MB firmware, +1MB OTA, 14MB filesystem (WEMOS D1 Mini pro, Ledunia (=32MB))
+;board_build.ldscript = eagle.flash.16m14m.ld
; set CPU frequency to 80MHz (default) or 160MHz
;board_build.f_cpu = 160000000L
From 37ee4e6d8eefac4ccc69e7f807b57c576773fa6c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 12 Jan 2021 17:18:56 +0100
Subject: [PATCH 34/71] Add optional file to most recent settings check
---
tasmota/settings.ino | 45 ++++++++++++++++++++++++++------------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/tasmota/settings.ino b/tasmota/settings.ino
index 2f9bad000..d61f66743 100644
--- a/tasmota/settings.ino
+++ b/tasmota/settings.ino
@@ -566,39 +566,48 @@ void SettingsSave(uint8_t rotate)
void SettingsLoad(void) {
#ifdef ESP8266
-#ifdef USE_UFILESYS
- if (TfsLoadFile(TASM_FILE_SETTINGS, (uint8_t*)&Settings, sizeof(Settings))) {
- settings_location = 1;
- AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded from File, " D_COUNT " %lu"), Settings.save_flag);
- } else {
-#endif
- // Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate
+ // Load configuration from optional file and flash (eeprom and 7 additonal slots) if first valid load does not stop_flash_rotate
// Activated with version 8.4.0.2 - Fails to read any config before version 6.6.0.11
settings_location = 0;
uint32_t save_flag = 0;
- uint32_t flash_location = FLASH_EEPROM_START;
- for (uint32_t i = 0; i <= CFG_ROTATES; i++) { // Read all config pages in search of valid and latest
- if (1 == i) { flash_location = SETTINGS_LOCATION; }
- ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
+ uint32_t max_slots = CFG_ROTATES +1;
+ uint32_t flash_location;
+ uint32_t slot = 1;
+#ifdef USE_UFILESYS
+ if (TfsLoadFile(TASM_FILE_SETTINGS, (uint8_t*)&Settings, sizeof(Settings))) {
+ flash_location = 1;
+ slot = 0;
+ }
+#endif
+ while (slot <= max_slots) { // Read all config pages in search of valid and latest
+ if (slot > 0) {
+ flash_location = (1 == slot) ? FLASH_EEPROM_START : (2 == slot) ? SETTINGS_LOCATION : flash_location -1;
+ ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
+ }
if ((Settings.cfg_crc32 != 0xFFFFFFFF) && (Settings.cfg_crc32 != 0x00000000) && (Settings.cfg_crc32 == GetSettingsCrc32())) {
- if (Settings.save_flag > save_flag) { // Find latest page based on incrementing save_flag
+ if (Settings.save_flag > save_flag) { // Find latest page based on incrementing save_flag
save_flag = Settings.save_flag;
settings_location = flash_location;
- if (Settings.flag.stop_flash_rotate && (0 == i)) { // Stop if only eeprom area should be used and it is valid
+ if (Settings.flag.stop_flash_rotate && (1 == slot)) { // Stop if only eeprom area should be used and it is valid
break;
}
}
}
- flash_location--;
+ slot++;
delay(1);
}
if (settings_location > 0) {
- ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
- AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
- }
#ifdef USE_UFILESYS
- }
+ if (1 == settings_location) {
+ TfsLoadFile(TASM_FILE_SETTINGS, (uint8_t*)&Settings, sizeof(Settings));
+ AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded from File, " D_COUNT " %lu"), Settings.save_flag);
+ } else
#endif
+ {
+ ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
+ AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
+ }
+ }
#endif // ESP8266
#ifdef ESP32
uint32_t source = SettingsRead(&Settings, sizeof(Settings));
From 800f86d56e3b85d19cf5344b18c83fa0aceb35bc Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 12 Jan 2021 19:31:15 +0100
Subject: [PATCH 35/71] Moving more to PROGMEM
---
tasmota/support_command.ino | 6 ++--
tasmota/support_tasmota.ino | 2 +-
tasmota/xdrv_01_webserver.ino | 32 +++++++++++-----------
tasmota/xdrv_02_mqtt.ino | 2 +-
tasmota/xdrv_09_timers.ino | 4 +--
tasmota/xdrv_10_scripter.ino | 4 +--
tasmota/xdrv_20_hue.ino | 2 +-
tasmota/xdrv_23_zigbee_2a_devices_impl.ino | 4 +--
tasmota/xdrv_23_zigbee_5_converters.ino | 4 +--
tasmota/xdrv_23_zigbee_7_5_map.ino | 2 +-
tasmota/xdrv_23_zigbee_A_impl.ino | 2 +-
tasmota/xdrv_28_pcf8574.ino | 6 ++--
tasmota/xdrv_50_filesystem.ino | 2 +-
13 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino
index 7faef10d5..0866d3f84 100644
--- a/tasmota/support_command.ino
+++ b/tasmota/support_command.ino
@@ -727,12 +727,12 @@ void CmndRestart(void)
switch (XdrvMailbox.payload) {
case 1:
TasmotaGlobal.restart_flag = 2;
- ResponseCmndChar(D_JSON_RESTARTING);
+ ResponseCmndChar(PSTR(D_JSON_RESTARTING));
break;
case 2:
TasmotaGlobal.restart_flag = 2;
TasmotaGlobal.restart_halt = true;
- ResponseCmndChar(D_JSON_HALTING);
+ ResponseCmndChar(PSTR(D_JSON_HALTING));
break;
case -1:
CmndCrash(); // force a crash
@@ -1208,7 +1208,7 @@ void CmndGpio(void)
if (jsflg2) {
ResponseClear();
} else {
- ResponseCmndChar(D_JSON_NOT_SUPPORTED);
+ ResponseCmndChar(PSTR(D_JSON_NOT_SUPPORTED));
}
}
}
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index 597435e40..a6e0b2104 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -1169,7 +1169,7 @@ void Every250mSeconds(void)
}
TasmotaGlobal.restart_flag--;
if (TasmotaGlobal.restart_flag <= 0) {
- AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "%s"), (TasmotaGlobal.restart_halt) ? "Halted" : D_RESTARTING);
+ AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "%s"), (TasmotaGlobal.restart_halt) ? PSTR("Halted") : PSTR(D_RESTARTING));
EspRestart();
}
}
diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino
index 229d9af1d..a86e8586b 100644
--- a/tasmota/xdrv_01_webserver.ino
+++ b/tasmota/xdrv_01_webserver.ino
@@ -475,14 +475,14 @@ void StartWebserver(int type, IPAddress ipweb)
String ipv6_addr = WifiGetIPv6();
if (ipv6_addr!="") {
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s and IPv6 global address %s "),
- NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str(), ipv6_addr.c_str());
+ NetworkHostname(), (Mdns.begun) ? PSTR(".local") : "", ipweb.toString().c_str(), ipv6_addr.c_str());
} else {
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"),
- NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str());
+ NetworkHostname(), (Mdns.begun) ? PSTR(".local") : "", ipweb.toString().c_str());
}
#else
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"),
- NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str());
+ NetworkHostname(), (Mdns.begun) ? PSTR(".local") : "", ipweb.toString().c_str());
#endif // LWIP_IPV6 = 1
TasmotaGlobal.rules_flag.http_init = 1;
}
@@ -744,7 +744,7 @@ void WSContentSendStyle_P(const char* formatP, ...)
bool sip = (static_cast(WiFi.softAPIP()) != 0);
WSContentSend_P(PSTR("%s%s (%s%s%s) "), // tasmota.local (192.168.2.12, 192.168.4.1)
NetworkHostname(),
- (Mdns.begun) ? ".local" : "",
+ (Mdns.begun) ? PSTR(".local") : "",
(lip) ? WiFi.localIP().toString().c_str() : "",
(lip && sip) ? ", " : "",
(sip) ? WiFi.softAPIP().toString().c_str() : "");
@@ -1230,15 +1230,15 @@ bool HandleRootStatusRefresh(void)
uint32_t fsize = (TasmotaGlobal.devices_present < 5) ? 70 - (TasmotaGlobal.devices_present * 8) : 32;
#ifdef USE_SONOFF_IFAN
if (IsModuleIfan()) {
- WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(TasmotaGlobal.power, 0)) ? "bold" : "normal", 54, GetStateText(bitRead(TasmotaGlobal.power, 0)));
+ WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(TasmotaGlobal.power, 0)) ? PSTR("bold") : PSTR("normal"), 54, GetStateText(bitRead(TasmotaGlobal.power, 0)));
uint32_t fanspeed = GetFanspeed();
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fanspeed);
- WSContentSend_P(HTTP_DEVICE_STATE, 64, (fanspeed) ? "bold" : "normal", 54, (fanspeed) ? svalue : GetStateText(0));
+ WSContentSend_P(HTTP_DEVICE_STATE, 64, (fanspeed) ? PSTR("bold") : PSTR("normal"), 54, (fanspeed) ? svalue : GetStateText(0));
} else {
#endif // USE_SONOFF_IFAN
for (uint32_t idx = 1; idx <= TasmotaGlobal.devices_present; idx++) {
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(TasmotaGlobal.power, idx -1));
- WSContentSend_P(HTTP_DEVICE_STATE, 100 / TasmotaGlobal.devices_present, (bitRead(TasmotaGlobal.power, idx -1)) ? "bold" : "normal", fsize, (TasmotaGlobal.devices_present < 5) ? GetStateText(bitRead(TasmotaGlobal.power, idx -1)) : svalue);
+ WSContentSend_P(HTTP_DEVICE_STATE, 100 / TasmotaGlobal.devices_present, (bitRead(TasmotaGlobal.power, idx -1)) ? PSTR("bold") : PSTR("normal"), fsize, (TasmotaGlobal.devices_present < 5) ? GetStateText(bitRead(TasmotaGlobal.power, idx -1)) : svalue);
}
#ifdef USE_SONOFF_IFAN
}
@@ -1438,7 +1438,7 @@ void HandleTemplateConfiguration(void)
for (uint32_t i = 0; i < MAX_GPIO_PIN; i++) {
if (!FlashPin(i)) {
WSContentSend_P(PSTR("" D_GPIO "%d "),
- ((9==i)||(10==i)) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? " style='width:150px'" : "", i, i);
+ ((9==i)||(10==i)) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? PSTR(" style='width:150px'") : "", i, i);
WSContentSend_P(PSTR(" "), i);
}
}
@@ -1824,7 +1824,7 @@ void HandleLoggingConfiguration(void)
idx);
for (uint32_t i = LOG_LEVEL_NONE; i <= LOG_LEVEL_DEBUG_MORE; i++) {
WSContentSend_P(PSTR("%d %s "),
- (i == llevel) ? " selected" : "", i, i,
+ (i == llevel) ? PSTR(" selected") : "", i, i,
GetTextIndexed(stemp1, sizeof(stemp1), i, kLoggingLevels));
}
WSContentSend_P(PSTR("
"));
@@ -1880,8 +1880,8 @@ void HandleOtherConfiguration(void)
TemplateJson();
char stemp[strlen(TasmotaGlobal.mqtt_data) +1];
strlcpy(stemp, TasmotaGlobal.mqtt_data, sizeof(stemp)); // Get JSON template
- WSContentSend_P(HTTP_FORM_OTHER, stemp, (USER_MODULE == Settings.module) ? " checked disabled" : "",
- (Settings.flag.mqtt_enabled) ? " checked" : "", // SetOption3 - Enable MQTT
+ WSContentSend_P(HTTP_FORM_OTHER, stemp, (USER_MODULE == Settings.module) ? PSTR(" checked disabled") : "",
+ (Settings.flag.mqtt_enabled) ? PSTR(" checked") : "", // SetOption3 - Enable MQTT
SettingsText(SET_FRIENDLYNAME1), SettingsText(SET_DEVICENAME));
uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!TasmotaGlobal.devices_present) ? 1 : TasmotaGlobal.devices_present;
@@ -1911,9 +1911,9 @@ void HandleOtherConfiguration(void)
if (i < EMUL_MAX) {
WSContentSend_P(PSTR("%s %s "), // Different id only used for labels
i, i,
- (i == Settings.flag2.emulation) ? " checked" : "",
+ (i == Settings.flag2.emulation) ? PSTR(" checked") : "",
GetTextIndexed(stemp, sizeof(stemp), i, kEmulationOptions),
- (i == EMUL_NONE) ? "" : (i == EMUL_WEMO) ? D_SINGLE_DEVICE : D_MULTI_DEVICE);
+ (i == EMUL_NONE) ? "" : (i == EMUL_WEMO) ? PSTR(D_SINGLE_DEVICE) : PSTR(D_MULTI_DEVICE));
}
}
WSContentSend_P(PSTR(""));
@@ -2086,7 +2086,7 @@ void HandleInformation(void)
#ifdef ESP32
#ifdef USE_ETHERNET
if (static_cast(EthernetLocalIP()) != 0) {
- WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? ".local" : "");
+ WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? PSTR(".local") : "");
WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str());
WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%s"), EthernetLocalIP().toString().c_str());
WSContentSend_P(PSTR("}1 }2 "));
@@ -2096,7 +2096,7 @@ void HandleInformation(void)
if (Settings.flag4.network_wifi) {
int32_t rssi = WiFi.RSSI();
WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, HtmlEscape(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str(), WifiGetRssiAsQuality(rssi), rssi);
- WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), TasmotaGlobal.hostname, (Mdns.begun) ? ".local" : "");
+ WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), TasmotaGlobal.hostname, (Mdns.begun) ? PSTR(".local") : "");
#if LWIP_IPV6
String ipv6_addr = WifiGetIPv6();
if (ipv6_addr != "") {
@@ -2788,7 +2788,7 @@ bool CaptivePortal(void)
if ((WifiIsInManagerMode()) && !ValidIpAddress(Webserver->hostHeader().c_str())) {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
- Webserver->sendHeader(F("Location"), String("http://") + Webserver->client().localIP().toString(), true);
+ Webserver->sendHeader(F("Location"), String(F("http://")) + Webserver->client().localIP().toString(), true);
WSSend(302, CT_PLAIN, ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
Webserver->client().stop(); // Stop is needed because we sent no content length
return true;
diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino
index dcd21930f..15e99f352 100644
--- a/tasmota/xdrv_02_mqtt.ino
+++ b/tasmota/xdrv_02_mqtt.ino
@@ -1275,7 +1275,7 @@ void HandleMqttConfiguration(void)
SettingsText(SET_MQTT_HOST),
Settings.mqtt_port,
#ifdef USE_MQTT_TLS
- Mqtt.mqtt_tls ? " checked" : "", // SetOption102 - Enable MQTT TLS
+ Mqtt.mqtt_tls ? PSTR(" checked") : "", // SetOption102 - Enable MQTT TLS
#endif // USE_MQTT_TLS
Format(str, MQTT_CLIENT_ID, sizeof(str)), MQTT_CLIENT_ID, SettingsText(SET_MQTT_CLIENT));
WSContentSend_P(HTTP_FORM_MQTT2,
diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino
index c40045a31..0f6292e13 100644
--- a/tasmota/xdrv_09_timers.ino
+++ b/tasmota/xdrv_09_timers.ino
@@ -305,7 +305,7 @@ void PrepShowTimer(uint32_t index)
char days[8] = { 0 };
for (uint32_t i = 0; i < 7; i++) {
uint8_t mask = 1 << i;
- snprintf(days, sizeof(days), "%s%d", days, ((xtimer.days & mask) > 0));
+ snprintf(days, sizeof(days), PSTR("%s%d"), days, ((xtimer.days & mask) > 0));
}
char soutput[80];
@@ -857,7 +857,7 @@ void HandleTimerConfiguration(void)
WSContentSend_P(HTTP_TIMER_SCRIPT5, MAX_TIMERS, TasmotaGlobal.devices_present);
WSContentSend_P(HTTP_TIMER_SCRIPT6, TasmotaGlobal.devices_present);
WSContentSendStyle_P(HTTP_TIMER_STYLE, WebColor(COL_FORM));
- WSContentSend_P(HTTP_FORM_TIMER1, (Settings.flag3.timers_enable) ? " checked" : ""); // CMND_TIMERS
+ WSContentSend_P(HTTP_FORM_TIMER1, (Settings.flag3.timers_enable) ? PSTR(" checked") : ""); // CMND_TIMERS
for (uint32_t i = 0; i < MAX_TIMERS; i++) {
WSContentSend_P(PSTR("%s%u"), (i > 0) ? "," : "", Settings.timer[i].data);
}
diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino
index 198e58077..cd07098f8 100755
--- a/tasmota/xdrv_10_scripter.ino
+++ b/tasmota/xdrv_10_scripter.ino
@@ -4979,9 +4979,9 @@ void HandleScriptConfiguration(void) {
#ifdef xSCRIPT_STRIP_COMMENTS
uint16_t ssize = glob_script_mem.script_size;
if (bitRead(Settings.rule_enabled, 1)) ssize *= 2;
- WSContentSend_P(HTTP_FORM_SCRIPT1,1,1,bitRead(Settings.rule_enabled,0) ? " checked" : "",ssize);
+ WSContentSend_P(HTTP_FORM_SCRIPT1,1,1,bitRead(Settings.rule_enabled,0) ? PSTR(" checked") : "",ssize);
#else
- WSContentSend_P(HTTP_FORM_SCRIPT1,1,1,bitRead(Settings.rule_enabled,0) ? " checked" : "",glob_script_mem.script_size);
+ WSContentSend_P(HTTP_FORM_SCRIPT1,1,1,bitRead(Settings.rule_enabled,0) ? PSTR(" checked") : "",glob_script_mem.script_size);
#endif
// script is to large for WSContentSend_P
diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino
index 84e9ed508..97eafbcba 100644
--- a/tasmota/xdrv_20_hue.ino
+++ b/tasmota/xdrv_20_hue.ino
@@ -175,7 +175,7 @@ String HueBridgeId(void)
String temp = WiFi.macAddress();
temp.replace(":", "");
String bridgeid = temp.substring(0, 6);
- bridgeid += "FFFE";
+ bridgeid += F("FFFE");
bridgeid += temp.substring(6);
return bridgeid; // 5CCF7FFFFE139F3D
}
diff --git a/tasmota/xdrv_23_zigbee_2a_devices_impl.ino b/tasmota/xdrv_23_zigbee_2a_devices_impl.ino
index 80a69441c..ec7d773e4 100644
--- a/tasmota/xdrv_23_zigbee_2a_devices_impl.ino
+++ b/tasmota/xdrv_23_zigbee_2a_devices_impl.ino
@@ -681,9 +681,9 @@ void Z_Device::jsonAddConfig(Z_attribute_list & attr_list) const {
for (auto & data_elt : data) {
char key[8];
if (data_elt.validConfig()) {
- snprintf_P(key, sizeof(key), "?%02X.%1X", data_elt.getEndpoint(), data_elt.getConfig());
+ snprintf_P(key, sizeof(key), PSTR("?%02X.%1X"), data_elt.getEndpoint(), data_elt.getConfig());
} else {
- snprintf_P(key, sizeof(key), "?%02X", data_elt.getEndpoint());
+ snprintf_P(key, sizeof(key), PSTR("?%02X"), data_elt.getEndpoint());
}
key[0] = Z_Data::DataTypeToChar(data_elt.getType());
arr_data.addStr(key);
diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino
index 5cfb19d06..fe4d219c0 100644
--- a/tasmota/xdrv_23_zigbee_5_converters.ino
+++ b/tasmota/xdrv_23_zigbee_5_converters.ino
@@ -1903,7 +1903,7 @@ void ZCLFrame::syntheticAqaraVibration(class Z_attribute_list &attr_list, class
y = buf2.get16(2);
x = buf2.get16(4);
char temp[32];
- snprintf_P(temp, sizeof(temp), "[%i,%i,%i]", x, y, z);
+ snprintf_P(temp, sizeof(temp), PSTR("[%i,%i,%i]"), x, y, z);
attr.setStrRaw(temp);
// calculate angles
float X = x;
@@ -1912,7 +1912,7 @@ void ZCLFrame::syntheticAqaraVibration(class Z_attribute_list &attr_list, class
int32_t Angle_X = 0.5f + atanf(X/sqrtf(z*z+y*y)) * f_180pi;
int32_t Angle_Y = 0.5f + atanf(Y/sqrtf(x*x+z*z)) * f_180pi;
int32_t Angle_Z = 0.5f + atanf(Z/sqrtf(x*x+y*y)) * f_180pi;
- snprintf_P(temp, sizeof(temp), "[%i,%i,%i]", Angle_X, Angle_Y, Angle_Z);
+ snprintf_P(temp, sizeof(temp), PSTR("[%i,%i,%i]"), Angle_X, Angle_Y, Angle_Z);
attr_list.addAttributePMEM(PSTR("AqaraAngles")).setStrRaw(temp);
}
}
diff --git a/tasmota/xdrv_23_zigbee_7_5_map.ino b/tasmota/xdrv_23_zigbee_7_5_map.ino
index 790720320..c9013b665 100644
--- a/tasmota/xdrv_23_zigbee_7_5_map.ino
+++ b/tasmota/xdrv_23_zigbee_7_5_map.ino
@@ -171,7 +171,7 @@ void Z_Mapper::dumpInternals(void) const {
char hex[8];
snprintf(hex, sizeof(hex), PSTR("%d"), edge.lqi);
- WSContentSend_P("{from:\"0x%04X\",to:\"0x%04X\",label:\"%s\",color:\"#%03X\"},",
+ WSContentSend_P(PSTR("{from:\"0x%04X\",to:\"0x%04X\",label:\"%s\",color:\"#%03X\"},"),
edge.node_1, edge.node_2, (edge.lqi > 0) ? hex : "", lqi_color);
}
WSContentSend_P(PSTR("],"));
diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino
index ce690c4db..ec9a454ac 100644
--- a/tasmota/xdrv_23_zigbee_A_impl.ino
+++ b/tasmota/xdrv_23_zigbee_A_impl.ino
@@ -2081,7 +2081,7 @@ void ZigbeeShow(bool json)
if (zigbee.permit_end_time) {
// PermitJoin in progress
- WSContentSend_P(msg[ZB_WEB_PERMITJOIN_ACTIVE], D_ZIGBEE_PERMITJOIN_ACTIVE);
+ WSContentSend_P(msg[ZB_WEB_PERMITJOIN_ACTIVE], PSTR(D_ZIGBEE_PERMITJOIN_ACTIVE));
}
#endif
}
diff --git a/tasmota/xdrv_28_pcf8574.ino b/tasmota/xdrv_28_pcf8574.ino
index 58bb5239c..93e8d825d 100644
--- a/tasmota/xdrv_28_pcf8574.ino
+++ b/tasmota/xdrv_28_pcf8574.ino
@@ -168,7 +168,7 @@ void HandlePcf8574(void)
WSContentStart_P(D_CONFIGURE_PCF8574);
WSContentSendStyle();
- WSContentSend_P(HTTP_FORM_I2C_PCF8574_1, (Settings.flag3.pcf8574_ports_inverted) ? " checked" : ""); // SetOption81 - Invert all ports on PCF8574 devices
+ WSContentSend_P(HTTP_FORM_I2C_PCF8574_1, (Settings.flag3.pcf8574_ports_inverted) ? PST(" checked") : ""); // SetOption81 - Invert all ports on PCF8574 devices
WSContentSend_P(HTTP_TABLE100);
for (uint32_t idx = 0; idx < Pcf8574.max_devices; idx++) {
for (uint32_t idx2 = 0; idx2 < 8; idx2++) { // 8 ports on PCF8574
@@ -177,8 +177,8 @@ void HandlePcf8574(void)
idx +1, idx2,
idx2 + 8*idx,
idx2 + 8*idx,
- ((helper & Settings.pcf8574_config[idx]) >> idx2 == 0) ? " selected " : " ",
- ((helper & Settings.pcf8574_config[idx]) >> idx2 == 1) ? " selected " : " "
+ ((helper & Settings.pcf8574_config[idx]) >> idx2 == 0) ? PSTR(" selected ") : " ",
+ ((helper & Settings.pcf8574_config[idx]) >> idx2 == 1) ? PSTR(" selected ") : " "
);
}
}
diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino
index 56d4ecfd8..dc4e93ab5 100644
--- a/tasmota/xdrv_50_filesystem.ino
+++ b/tasmota/xdrv_50_filesystem.ino
@@ -502,7 +502,7 @@ void UfsDirectory(void) {
WSContentSend_P(UFS_FORM_FILE_UPGc, WebColor(COL_TEXT), ts, fs);
if (ufs_dir) {
- WSContentSend_P(UFS_FORM_FILE_UPGc1, WiFi.localIP().toString().c_str(),ufs_dir == 1 ? 2:1, ufs_dir == 1 ? "SDCard":"FlashFS");
+ WSContentSend_P(UFS_FORM_FILE_UPGc1, WiFi.localIP().toString().c_str(),ufs_dir == 1 ? 2:1, ufs_dir == 1 ? PSTR("SDCard"):PSTR("FlashFS"));
}
WSContentSend_P(UFS_FORM_FILE_UPGc2);
From 35d9ac9042ce91f39fbf8c4af541752ce4f9d071 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 12 Jan 2021 19:48:28 +0100
Subject: [PATCH 36/71] Removed crash logger from BearSSL It is generally not
useful since ESP8266 crashed before we reach this point
---
tasmota/StackThunk_light.cpp | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/tasmota/StackThunk_light.cpp b/tasmota/StackThunk_light.cpp
index aea7ae438..8f8b9a23a 100644
--- a/tasmota/StackThunk_light.cpp
+++ b/tasmota/StackThunk_light.cpp
@@ -121,26 +121,26 @@ uint32_t stack_thunk_light_get_max_usage()
}
/* Print the stack from the first used 16-byte chunk to the top, decodable by the exception decoder */
-void stack_thunk_light_dump_stack()
-{
- uint32_t *pos = stack_thunk_light_top;
- while (pos < stack_thunk_light_ptr) {
- if ((pos[0] != _stackPaint) || (pos[1] != _stackPaint) || (pos[2] != _stackPaint) || (pos[3] != _stackPaint))
- break;
- pos += 4;
- }
- ets_printf(">>>stack>>>\n");
- while (pos < stack_thunk_light_ptr) {
- ets_printf("%08x: %08x %08x %08x %08x\n", (int32_t)pos, pos[0], pos[1], pos[2], pos[3]);
- pos += 4;
- }
- ets_printf("<<>>stack>>>\n");
+// while (pos < stack_thunk_light_ptr) {
+// ets_printf("%08x: %08x %08x %08x %08x\n", (int32_t)pos, pos[0], pos[1], pos[2], pos[3]);
+// pos += 4;
+// }
+// ets_printf("<<
Date: Tue, 12 Jan 2021 23:04:42 +0100
Subject: [PATCH 37/71] SeeSoil State Machine Flavor
---
tasmota/xsns_81_seesaw_soil.ino | 375 ++++++++++++++++++++------------
1 file changed, 230 insertions(+), 145 deletions(-)
diff --git a/tasmota/xsns_81_seesaw_soil.ino b/tasmota/xsns_81_seesaw_soil.ino
index 1e37d6608..87c679a1a 100644
--- a/tasmota/xsns_81_seesaw_soil.ino
+++ b/tasmota/xsns_81_seesaw_soil.ino
@@ -22,16 +22,24 @@
#ifdef USE_SEESAW_SOIL
/*********************************************************************************************\
- * SEESAW_SOIL - Capacitance & Temperature Sensor
+ * SEESAW_SOIL - Capacitice Soil Moisture & Temperature Sensor
*
* I2C Address: 0x36, 0x37, 0x38, 0x39
*
- * Memory footprint: 1296 bytes flash, 64 bytes RAM
+ * This version of the driver replaces all delay loops by a state machine. So the number
+ * of instruction cycles consumed has been reduced dramatically. The sensors are reset,
+ * detected, commanded and read all at once. So the reading times won't increase with the
+ * number of sensors attached. The detection of sensors does not happen in FUNC_INIT any
+ * more. All i2c handling happens in the 50ms state machine.
+ * The memory footprint has suffered a little bit from this redesign, naturally.
+ *
+ * Memory footprint: 1444 bytes flash / 68 bytes RAM
*
* NOTE: #define SEESAW_SOIL_PUBLISH enables immediate MQTT on soil moisture change
* otherwise the moisture value will only be emitted every TelePeriod
* #define SEESAW_SOIL_RAW enables displaying analog capacitance input in the
* web page for calibration purposes
+ * #define SEESAW_SOIL_PERSISTENT_NAMING to get sensor names indexed by i2c address
\*********************************************************************************************/
#define XSNS_81 81
@@ -39,209 +47,281 @@
#include "Adafruit_seesaw.h" // we only use definitions, no code
-//#define SEESAW_SOIL_RAW // enable raw readings
-//#define SEESAW_SOIL_PUBLISH // enable immediate publish
-//#define SEESAW_SOIL_PERSISTENT_NAMING // enable naming sensors by i2c address
-//#define DEBUG_SEESAW_SOIL // enable debugging
-
#define SEESAW_SOIL_MAX_SENSORS 4
#define SEESAW_SOIL_START_ADDRESS 0x36
+ // I2C state machine
+#define STATE_IDLE 0x00
+#define STATE_RESET 0x01
+#define STATE_INIT 0x02
+#define STATE_DETECT 0x04
+#define STATE_COMMAND_TEMP 0x08
+#define STATE_READ_TEMP 0x10
+#define STATE_COMMAND_MOIST 0x20
+#define STATE_READ_MOIST 0x40
+ // I2C commands
+#define COMMAND_RESET 0x01
+#define COMMAND_ID 0x02
+#define COMMAND_TEMP 0x04
+#define COMMAND_MOIST 0x08
+ // I2C delays
+#define DELAY_DETECT 1 // ms delay before reading ID
+#define DELAY_TEMP 1 // ms delay between command and reading
+#define DELAY_MOIST 5 // ms delay between command and reading
+#define DELAY_RESET 500 // ms delay after slave reset
-const char SeeSoilName[] = "SeeSoil"; // spaces not allowed for Homeassistant integration/mqtt topics
-uint8_t SeeSoilCount = 0; // global sensor count
+// Convert capacitance into a moisture.
+// From observation, a free air reading is at 320, immersed in tap water, reading is 1014
+// So let's make a scale that converts those (apparent) facts into a percentage
+#define MAX_CAPACITANCE 1020.0f // subject to calibration
+#define MIN_CAPACITANCE 320 // subject to calibration
+#define CAP_TO_MOIST(c) ((max((int)(c),MIN_CAPACITANCE)-MIN_CAPACITANCE)/(MAX_CAPACITANCE-MIN_CAPACITANCE)*100)
struct SEESAW_SOIL {
- uint8_t address; // i2c address
- float moisture;
- float temperature;
-#ifdef SEESAW_SOIL_RAW
- uint16_t capacitance; // raw analog reading
-#endif // SEESAW_SOIL_RAW
-} SeeSoil[SEESAW_SOIL_MAX_SENSORS];
+ const char name[8] = "SeeSoil"; // spaces not allowed for Homeassistant integration/mqtt topics
+ uint8_t count = 0; // global sensor count (0xFF = not initialized)
+ uint8_t state = STATE_IDLE; // current state
+ bool present = false; // driver active
+} SeeSoil;
-// Used to convert capacitance into a moisture.
-// From observation, a free air reading is at 320
-// Immersed in tap water, reading is 1014
-// Appears to be a 10-bit device, readings close to 1020
-// So let's make a scale that converts those (apparent) facts into a percentage
-#define MAX_CAPACITANCE 1020.0f // subject to calibration
-#define MIN_CAPACITANCE 320 // subject to calibration
-#define CAP_TO_MOIST(c) ((max((int)(c),MIN_CAPACITANCE)-MIN_CAPACITANCE)/(MAX_CAPACITANCE-MIN_CAPACITANCE)*100)
+struct SEESAW_SOIL_SNS {
+ uint8_t address; // i2c address
+ float moisture;
+ float temperature;
+#ifdef SEESAW_SOIL_RAW
+ uint16_t capacitance; // raw analog reading
+#endif // SEESAW_SOIL_RAW
+} SeeSoilSNS[SEESAW_SOIL_MAX_SENSORS];
/*********************************************************************************************\
* i2c routines
\*********************************************************************************************/
-void SEESAW_SOILDetect(void) {
- uint8_t buf;
- uint32_t i, addr;
-
- for (i = 0; i < SEESAW_SOIL_MAX_SENSORS; i++) {
- addr = SEESAW_SOIL_START_ADDRESS + i;
- if ( ! I2cSetDevice(addr)) { continue; }
- delay(1);
- SEESAW_Reset(addr); // reset all seesaw MCUs at once
+void seeSoilInit(void) {
+ for (int i = 0; i < SEESAW_SOIL_MAX_SENSORS; i++) {
+ int addr = SEESAW_SOIL_START_ADDRESS + i;
+ if ( ! I2cSetDevice(addr) ) { continue; }
+ seeSoilCommand(COMMAND_RESET);
}
- delay(500); // give MCUs time to boot
- for (i = 0; i < SEESAW_SOIL_MAX_SENSORS; i++) {
- addr = SEESAW_SOIL_START_ADDRESS + i;
+ SeeSoil.state = STATE_RESET;
+ SeeSoil.present = true;
+}
+
+void seeSoilEvery50ms(void){ // i2c state machine
+ static uint32_t state_time;
+
+ uint32_t time_diff = millis() - state_time;
+
+ switch (SeeSoil.state) {
+ case STATE_RESET: // reset was just issued
+ SeeSoil.state = STATE_INIT;
+ break;
+ case STATE_INIT: // wait for sensors to settle
+ if (time_diff < DELAY_RESET) { return; }
+ seeSoilCommand(COMMAND_ID); // send hardware id commands
+ SeeSoil.state = STATE_DETECT;
+ break;
+ case STATE_DETECT: // detect sensors
+ if (time_diff < DELAY_DETECT) { return; }
+ seeSoilDetect();
+ SeeSoil.state=STATE_COMMAND_TEMP;
+ break;
+ case STATE_COMMAND_TEMP: // send temperature commands
+ seeSoilCommand(COMMAND_TEMP);
+ SeeSoil.state = STATE_READ_TEMP;
+ break;
+ case STATE_READ_TEMP:
+ if (time_diff < DELAY_TEMP) { return; }
+ seeSoilRead(COMMAND_TEMP); // read temperature values
+ SeeSoil.state = STATE_COMMAND_MOIST;
+ break;
+ case STATE_COMMAND_MOIST: // send moisture commands
+ seeSoilCommand(COMMAND_MOIST);
+ SeeSoil.state = STATE_READ_MOIST;
+ break;
+ case STATE_READ_MOIST:
+ if (time_diff < DELAY_MOIST) { return; }
+ seeSoilRead(COMMAND_MOIST); // read moisture values
+ SeeSoil.state = STATE_COMMAND_TEMP;
+ break;
+ }
+ state_time = millis();
+}
+
+void seeSoilDetect(void) { // detect sensors
+ uint8_t buf;
+
+ SeeSoil.count = 0;
+ SeeSoil.present = false;
+ for (int i = 0; i < SEESAW_SOIL_MAX_SENSORS; i++) {
+ uint32_t addr = SEESAW_SOIL_START_ADDRESS + i;
if ( ! I2cSetDevice(addr)) { continue; }
- if ( ! SEESAW_ValidRead(addr, SEESAW_STATUS_BASE, SEESAW_STATUS_HW_ID, &buf, 1, 0)) {
- continue;
- }
- if (buf != SEESAW_HW_ID_CODE) {
+ if (1 != Wire.requestFrom((uint8_t) addr, (uint8_t) 1)) { continue; }
+ buf = (uint8_t) Wire.read();
+ if (buf != SEESAW_HW_ID_CODE) { // check hardware id
#ifdef DEBUG_SEESAW_SOIL
AddLog_P(LOG_LEVEL_DEBUG, PSTR("SEE: HWID mismatch ADDR=%X, ID=%X"), addr, buf);
#endif // DEBUG_SEESAW_SOIL
continue;
}
- SeeSoil[SeeSoilCount].address = addr;
- SeeSoil[SeeSoilCount].temperature = NAN;
- SeeSoil[SeeSoilCount].moisture = NAN;
- #ifdef SEESAW_SOIL_RAW
- SeeSoil[SeeSoilCount].capacitance = 0; // raw analog reading
-#endif // SEESAW_SOIL_RAW
- I2cSetActiveFound(SeeSoil[SeeSoilCount].address, SeeSoilName);
- SeeSoilCount++;
- }
-}
-
-float SEESAW_Temp(uint8_t addr) { // get temperature from seesaw at addr
- uint8_t buf[4];
-
- if (SEESAW_ValidRead(addr, SEESAW_STATUS_BASE, SEESAW_STATUS_TEMP, buf, 4, 1000)) {
- int32_t ret = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
- ((uint32_t)buf[2] << 8) | (uint32_t)buf[3];
- return ConvertTemp((1.0 / (1UL << 16)) * ret);
- }
- return NAN;
-}
-
-float SEESAW_Moist(uint8_t addr) { // get moisture from seesaw at addr
- uint8_t buf[2];
- uint16_t ret;
- int32_t tries = 2;
-
- while (tries--) {
- delay(1);
- if (SEESAW_ValidRead(addr, SEESAW_TOUCH_BASE, SEESAW_TOUCH_CHANNEL_OFFSET, buf, 2, 3000)) {
- ret = ((uint16_t)buf[0] << 8) | buf[1];
+ SeeSoilSNS[SeeSoil.count].address = addr;
+ SeeSoilSNS[SeeSoil.count].temperature = NAN;
+ SeeSoilSNS[SeeSoil.count].moisture = NAN;
#ifdef SEESAW_SOIL_RAW
- for (int i=0; i < SeeSoilCount; i++) {
- if (SeeSoil[i].address == addr) {
- SeeSoil[i].capacitance = ret;
- break;
- }
- }
+ SeeSoilSNS[SeeSoil.count].capacitance = 0; // raw analog reading
#endif // SEESAW_SOIL_RAW
- if (ret != 0xFFFF) { return (float) CAP_TO_MOIST(ret); }
+ I2cSetActiveFound(SeeSoilSNS[SeeSoil.count].address, SeeSoil.name);
+ SeeSoil.count++;
+ SeeSoil.present = true;
+#ifdef DEBUG_SEESAW_SOIL
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR("SEE: FOUND sensor %u at %02X"), i, addr);
+#endif // DEBUG_SEESAW_SOIL
+ }
+}
+
+void seeSoilCommand(uint32_t command) { // issue commands to sensors
+ uint8_t regLow;
+ uint8_t regHigh = SEESAW_STATUS_BASE;
+ uint32_t count = SeeSoil.count;
+
+ switch (command) {
+ case COMMAND_RESET:
+ count = SEESAW_SOIL_MAX_SENSORS;
+ regLow = SEESAW_STATUS_SWRST;
+ break;
+ case COMMAND_ID:
+ count = SEESAW_SOIL_MAX_SENSORS;
+ regLow = SEESAW_STATUS_HW_ID;
+ break;
+ case COMMAND_TEMP:
+ regLow = SEESAW_STATUS_TEMP;
+ break;
+ case COMMAND_MOIST:
+ regHigh = SEESAW_TOUCH_BASE;
+ regLow = SEESAW_TOUCH_CHANNEL_OFFSET;
+ break;
+ default:
+#ifdef DEBUG_SEESAW_SOIL
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR("SEE: ILL CMD:%02X"), command);
+#endif // DEBUG_SEESAW_SOIL
+ return;
+ }
+ for (int i = 0; i < count; i++) {
+ uint32_t addr = (command & (COMMAND_RESET|COMMAND_ID)) ? SEESAW_SOIL_START_ADDRESS + i : SeeSoilSNS[i].address;
+ Wire.beginTransmission((uint8_t) addr);
+ Wire.write((uint8_t) regHigh);
+ Wire.write((uint8_t) regLow);
+ uint32_t err = Wire.endTransmission();
+#ifdef DEBUG_SEESAW_SOIL
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR("SEE: SNS=%u ADDR=%02X CMD=%02X ERR=%u"), i, addr, command, err);
+#endif // DEBUG_SEESAW_SOIL
}
- }
- return NAN;
}
-bool SEESAW_ValidRead(uint8_t addr, uint8_t regHigh, uint8_t regLow, // read from seesaw sensor
- uint8_t *buf, uint8_t num, uint16_t delay) {
+void seeSoilRead(uint32_t command) { // read values from sensors
+ uint8_t buf[4];
+ uint32_t num;
+ int32_t ret;
- Wire.beginTransmission((uint8_t) addr);
- Wire.write((uint8_t) regHigh);
- Wire.write((uint8_t) regLow);
- int err = Wire.endTransmission();
- if (err) { return false; }
- delayMicroseconds(delay);
- if (num != Wire.requestFrom((uint8_t) addr, (uint8_t) num)) {
- return false;
- }
- for (int i = 0; i < num; i++) {
- buf[i] = (uint8_t) Wire.read();
- }
- return true;
-}
+ num = (command == COMMAND_TEMP) ? 4 : 2; // response size in bytes
-bool SEESAW_Reset(uint8_t addr) { // init sensor MCU
- Wire.beginTransmission((uint8_t) addr);
- Wire.write((uint8_t) SEESAW_STATUS_BASE);
- Wire.write((uint8_t) SEESAW_STATUS_SWRST);
- return (Wire.endTransmission() == 0);
+ for (int i = 0; i < SeeSoil.count; i++) { // for all sensors
+ if (num != Wire.requestFrom((uint8_t) SeeSoilSNS[i].address, (uint8_t) num)) { continue; }
+ bzero(buf, sizeof(buf));
+ for (int b = 0; b < num; b++) {
+ buf[b] = (uint8_t) Wire.read();
+ }
+ if (command == COMMAND_TEMP) {
+ ret = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
+ ((uint32_t)buf[2] << 8) | (uint32_t)buf[3];
+ SeeSoilSNS[i].temperature = ConvertTemp((1.0 / (1UL << 16)) * ret);
+ } else { // COMMAND_MOIST
+ ret = (uint32_t)buf[0] << 8 | (uint32_t)buf[1];
+ SeeSoilSNS[i].moisture = CAP_TO_MOIST(ret);
+#ifdef SEESAW_SOIL_RAW
+ SeeSoilSNS[i].capacitance = ret;
+#endif // SEESAW_SOIL_RAW
+ }
+#ifdef DEBUG_SEESAW_SOIL
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR("SEE: READ #%u ADDR=%02X NUM=%u RET=%X"), i, SeeSoilSNS[i].address, num, ret);
+#endif // DEBUG_SEESAW_SOIL
+ }
}
/*********************************************************************************************\
* JSON routines
\*********************************************************************************************/
-void SEESAW_SOILEverySecond(void) { // update sensor values and publish if changed
#ifdef SEESAW_SOIL_PUBLISH
- uint32_t old_moist;
-#endif // SEESAW_SOIL_PUBLISH
+void seeSoilEverySecond(void) { // update sensor values and publish if changed
+ static uint16_t old_moist[SEESAW_SOIL_MAX_SENSORS];
+ static bool firstcall = true;
- for (int i = 0; i < SeeSoilCount; i++) {
- SeeSoil[i].temperature = SEESAW_Temp(SeeSoil[i].address);
-#ifdef SEESAW_SOIL_PUBLISH
- old_moist = (uint32_t) SeeSoil[i].moisture;
-#endif // SEESAW_SOIL_PUBLISH
- SeeSoil[i].moisture = SEESAW_Moist(SeeSoil[i].address);
-#ifdef SEESAW_SOIL_PUBLISH
- if ((uint32_t) SeeSoil[i].moisture != old_moist) {
- Response_P(PSTR("{")); // send values to MQTT & rules
- SEESAW_SOILJson(i);
- ResponseJsonEnd();
- MqttPublishTeleSensor();
+ for (int i = 0; i < SeeSoil.count; i++) {
+ if (firstcall) { firstcall = false; }
+ else {
+ if ((uint32_t) SeeSoilSNS[i].moisture != old_moist[i]) {
+ Response_P(PSTR("{")); // send values to MQTT & rules
+ seeSoilJson(i);
+ ResponseJsonEnd();
+ MqttPublishTeleSensor();
+ }
}
-#endif // SEESAW_SOIL_PUBLISH
+ old_moist[i] = (uint32_t) SeeSoilSNS[i].moisture;
}
}
+#endif // SEESAW_SOIL_PUBLISH
-void SEESAW_SOILShow(bool json) {
+void seeSoilShow(bool json) {
char temperature[FLOATSZ];
- char sensor_name[sizeof(SeeSoilName) + 3];
+ char sensor_name[sizeof(SeeSoil.name) + 3];
- for (uint32_t i = 0; i < SeeSoilCount; i++) {
- dtostrfd(SeeSoil[i].temperature, Settings.flag2.temperature_resolution, temperature);
- SEESAW_SOILName(i, sensor_name, sizeof(sensor_name));
+ for (uint32_t i = 0; i < SeeSoil.count; i++) {
+ dtostrfd(SeeSoilSNS[i].temperature, Settings.flag2.temperature_resolution, temperature);
+ seeSoilName(i, sensor_name, sizeof(sensor_name));
if (json) {
- ResponseAppend_P(PSTR(",")); // compose tele json
- SEESAW_SOILJson(i);
+ ResponseAppend_P(PSTR(",")); // compose tele json
+ seeSoilJson(i);
if (0 == TasmotaGlobal.tele_period) {
#ifdef USE_DOMOTICZ
- DomoticzTempHumPressureSensor(SeeSoil[i].temperature, SeeSoil[i].moisture, -42.0f);
+ DomoticzTempHumPressureSensor(SeeSoilSNS[i].temperature, SeeSoilSNS[i].moisture, -42.0f);
#endif // USE_DOMOTICZ
#ifdef USE_KNX
- KnxSensor(KNX_TEMPERATURE, SeeSoil[i].temperature);
- KnxSensor(KNX_HUMIDITY, SeeSoil[i].moisture);
+ KnxSensor(KNX_TEMPERATURE, SeeSoilSNS[i].temperature);
+ KnxSensor(KNX_HUMIDITY, SeeSoilSNS[i].moisture);
#endif // USE_KNX
}
#ifdef USE_WEBSERVER
} else {
#ifdef SEESAW_SOIL_RAW
- WSContentSend_PD(HTTP_SNS_ANALOG, sensor_name, 0, SeeSoil[i].capacitance);
+ WSContentSend_PD(HTTP_SNS_ANALOG, sensor_name, 0, SeeSoilSNS[i].capacitance);
#endif // SEESAW_SOIL_RAW
- WSContentSend_PD(HTTP_SNS_MOISTURE, sensor_name, (uint32_t) SeeSoil[i].moisture);
+ WSContentSend_PD(HTTP_SNS_MOISTURE, sensor_name, (uint32_t) SeeSoilSNS[i].moisture);
WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, temperature, TempUnit());
#endif // USE_WEBSERVER
}
} // for each sensor connected
}
-void SEESAW_SOILJson(int no) { // common json
+void seeSoilJson(int no) { // common json
char temperature[FLOATSZ];
- char sensor_name[sizeof(SeeSoilName) + 3];
+ char sensor_name[sizeof(SeeSoil.name) + 3];
- SEESAW_SOILName(no, sensor_name, sizeof(sensor_name));
- dtostrfd(SeeSoil[no].temperature, Settings.flag2.temperature_resolution, temperature);
+ seeSoilName(no, sensor_name, sizeof(sensor_name));
+ dtostrfd(SeeSoilSNS[no].temperature, Settings.flag2.temperature_resolution, temperature);
ResponseAppend_P(PSTR ("\"%s\":{\"" D_JSON_ID "\":\"%02X\",\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_MOISTURE "\":%u}"),
- sensor_name, SeeSoil[no].address, temperature, (uint32_t) SeeSoil[no].moisture);
+ sensor_name, SeeSoilSNS[no].address, temperature, (uint32_t) SeeSoilSNS[no].moisture);
}
-void SEESAW_SOILName(int no, char *name, int len) // generates a sensor name
+void seeSoilName(int no, char *name, int len) // generates a sensor name
{
#ifdef SEESAW_SOIL_PERSISTENT_NAMING
- snprintf_P(name, len, PSTR("%s%c%02X"), SeeSoilName, IndexSeparator(), SeeSoil[no].address);
+ snprintf_P(name, len, PSTR("%s%c%02X"), SeeSoil.name, IndexSeparator(), SeeSoilSNS[no].address);
#else
- if (SeeSoilCount > 1) {
- snprintf_P(name, len, PSTR("%s%c%u"), SeeSoilName, IndexSeparator(), no + 1);
+ if (SeeSoil.count > 1) {
+ snprintf_P(name, len, PSTR("%s%c%u"), SeeSoil.name, IndexSeparator(), no + 1);
}
else {
- strlcpy(name, SeeSoilName, len);
+ strlcpy(name, SeeSoil.name, len);
}
#endif // SEESAW_SOIL_PERSISTENT_NAMING
}
@@ -256,19 +336,24 @@ bool Xsns81(uint8_t function)
bool result = false;
if (FUNC_INIT == function) {
- SEESAW_SOILDetect();
+ seeSoilInit();
}
- else if (SeeSoilCount){
+ else if (SeeSoil.present){
switch (function) {
- case FUNC_EVERY_SECOND:
- SEESAW_SOILEverySecond();
+ case FUNC_EVERY_50_MSECOND:
+ seeSoilEvery50ms();
break;
+ #ifdef SEESAW_SOIL_PUBLISH
+ case FUNC_EVERY_SECOND:
+ seeSoilEverySecond();
+ break;
+ #endif // SEESAW_SOIL_PUBLISH
case FUNC_JSON_APPEND:
- SEESAW_SOILShow(1);
+ seeSoilShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
- SEESAW_SOILShow(0);
+ seeSoilShow(0);
break;
#endif // USE_WEBSERVER
}
From be531c9c816d0d2558284180fdf43018823a6446 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Wed, 13 Jan 2021 08:27:40 +0100
Subject: [PATCH 38/71] Fixing compile error
---
tasmota/xdrv_28_pcf8574.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/xdrv_28_pcf8574.ino b/tasmota/xdrv_28_pcf8574.ino
index 93e8d825d..b79f3caa6 100644
--- a/tasmota/xdrv_28_pcf8574.ino
+++ b/tasmota/xdrv_28_pcf8574.ino
@@ -168,7 +168,7 @@ void HandlePcf8574(void)
WSContentStart_P(D_CONFIGURE_PCF8574);
WSContentSendStyle();
- WSContentSend_P(HTTP_FORM_I2C_PCF8574_1, (Settings.flag3.pcf8574_ports_inverted) ? PST(" checked") : ""); // SetOption81 - Invert all ports on PCF8574 devices
+ WSContentSend_P(HTTP_FORM_I2C_PCF8574_1, (Settings.flag3.pcf8574_ports_inverted) ? PSTR(" checked") : ""); // SetOption81 - Invert all ports on PCF8574 devices
WSContentSend_P(HTTP_TABLE100);
for (uint32_t idx = 0; idx < Pcf8574.max_devices; idx++) {
for (uint32_t idx2 = 0; idx2 < 8; idx2++) { // 8 ports on PCF8574
From a1c586b145428bf58156e148411cf1b69815c081 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Wed, 13 Jan 2021 09:26:31 +0100
Subject: [PATCH 39/71] Use ESP32 1.0.5rc6 for ESP32 stage
---
platformio_override_sample.ini | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index 344faeea3..3b82447f2 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -144,11 +144,11 @@ lib_extra_dirs = ${library.lib_extra_dirs}
[core32_stage]
-platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2452c1fb539246e47a715b74a3ad25b8a7ebbec7
+platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/tag/1.0.5-rc6
platformio/tool-mklittlefs @ ~1.203.200522
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags}
- -DESP32_STAGE=true
+ ;-DESP32_STAGE=true
[library]
lib_ldf_mode = chain+
From a34f75f44c440f5b68681b25fe5b99271d53fb2c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 13 Jan 2021 12:12:14 +0100
Subject: [PATCH 40/71] Fix locale File Management decimal point
---
tasmota/xdrv_01_webserver.ino | 16 ++++++-------
tasmota/xdrv_50_filesystem.ino | 44 ++++++----------------------------
2 files changed, 15 insertions(+), 45 deletions(-)
diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino
index a86e8586b..d68cf9cd0 100644
--- a/tasmota/xdrv_01_webserver.ino
+++ b/tasmota/xdrv_01_webserver.ino
@@ -2169,15 +2169,15 @@ void HandleInformation(void)
#ifdef ESP8266
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP.getFlashChipId());
#endif
- WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%dkB"), ESP.getFlashChipRealSize() / 1024);
- WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%dkB"), ESP.getFlashChipSize() / 1024);
- WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%dkB"), ESP_getSketchSize() / 1024);
- WSContentSend_P(PSTR("}1" D_FREE_PROGRAM_SPACE "}2%dkB"), ESP.getFreeSketchSpace() / 1024);
- WSContentSend_P(PSTR("}1" D_FREE_MEMORY "}2%dkB"), freeMem / 1024);
+ WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%d kB"), ESP.getFlashChipRealSize() / 1024);
+ WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%d kB"), ESP.getFlashChipSize() / 1024);
+ WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%d kB"), ESP_getSketchSize() / 1024);
+ WSContentSend_P(PSTR("}1" D_FREE_PROGRAM_SPACE "}2%d kB"), ESP.getFreeSketchSpace() / 1024);
+ WSContentSend_P(PSTR("}1" D_FREE_MEMORY "}2%d kB"), freeMem / 1024);
#ifdef ESP32
if (psramFound()) {
- WSContentSend_P(PSTR("}1" D_PSR_MAX_MEMORY "}2%dkB"), ESP.getPsramSize() / 1024);
- WSContentSend_P(PSTR("}1" D_PSR_FREE_MEMORY "}2%dkB"), ESP.getFreePsram() / 1024);
+ WSContentSend_P(PSTR("}1" D_PSR_MAX_MEMORY "}2%d kB"), ESP.getPsramSize() / 1024);
+ WSContentSend_P(PSTR("}1" D_PSR_FREE_MEMORY "}2%d kB"), ESP.getFreePsram() / 1024);
}
#endif
WSContentSend_P(PSTR(""));
@@ -2522,7 +2522,7 @@ void HandleUploadLoop(void) {
return;
}
if (upload.totalSize && !(upload.totalSize % 102400)) {
- AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "Progress %dkB"), upload.totalSize / 1024);
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "Progress %d kB"), upload.totalSize / 1024);
}
}
diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino
index dc4e93ab5..8066a9b93 100644
--- a/tasmota/xdrv_50_filesystem.ino
+++ b/tasmota/xdrv_50_filesystem.ino
@@ -274,32 +274,6 @@ uint8_t UfsReject(char *name) {
return 0;
}
-// Format number with thousand marker - Not international as '.' is decimal on most countries
-void UfsForm1000(uint32_t number, char *dp, char sc) {
- char str[32];
- sprintf(str, "%d", number);
- char *sp = str;
- uint32_t inum = strlen(sp)/3;
- uint32_t fnum = strlen(sp)%3;
- if (!fnum) { inum--; }
- for (uint32_t count = 0; count <= inum; count++) {
- if (fnum) {
- memcpy(dp, sp, fnum);
- dp += fnum;
- sp += fnum;
- fnum = 0;
- } else {
- memcpy(dp, sp, 3);
- dp += 3;
- sp += 3;
- }
- if (count != inum) {
- *dp++ = sc;
- }
- }
- *dp = 0;
-}
-
/*********************************************************************************************\
* Tfs low level functions
\*********************************************************************************************/
@@ -418,7 +392,7 @@ const char UFS_FORM_FILE_UPLOAD[] PROGMEM =
""
"
" D_MANAGE_FILE_SYSTEM " ";
const char UFS_FORM_FILE_UPGc[] PROGMEM =
- "" D_FS_SIZE " %s kB - " D_FS_FREE " %s kB";
+ "
" D_FS_SIZE " %s MB - " D_FS_FREE " %s MB";
const char UFS_FORM_FILE_UPGc1[] PROGMEM =
"
%s ";
@@ -451,7 +425,6 @@ const char UFS_FORM_SDC_HREFdel[] PROGMEM =
"
🔥 "; // 🔥
#endif // GUI_TRASH_FILE
-
void UfsDirectory(void) {
if (!HttpCheckPriviledgedAccess()) { return; }
@@ -461,8 +434,6 @@ void UfsDirectory(void) {
strcpy(ufs_path, "/");
-
-
if (Webserver->hasArg("download")) {
String stmp = Webserver->arg("download");
char *cp = (char*)stmp.c_str();
@@ -494,15 +465,14 @@ void UfsDirectory(void) {
WSContentSendStyle();
WSContentSend_P(UFS_FORM_FILE_UPLOAD);
- char ts[16];
- char fs[16];
- UfsForm1000(UfsInfo(0, ufs_dir == 2 ? 1:0), ts, '.');
- UfsForm1000(UfsInfo(1, ufs_dir == 2 ? 1:0), fs, '.');
-
- WSContentSend_P(UFS_FORM_FILE_UPGc, WebColor(COL_TEXT), ts, fs);
+ char ts[FLOATSZ];
+ dtostrfd((float)UfsInfo(0, ufs_dir == 2 ? 1:0) / 1000, 3, ts);
+ char fs[FLOATSZ];
+ dtostrfd((float)UfsInfo(1, ufs_dir == 2 ? 1:0) / 1000, 3, fs);
+ WSContentSend_PD(UFS_FORM_FILE_UPGc, WebColor(COL_TEXT), ts, fs);
if (ufs_dir) {
- WSContentSend_P(UFS_FORM_FILE_UPGc1, WiFi.localIP().toString().c_str(),ufs_dir == 1 ? 2:1, ufs_dir == 1 ? PSTR("SDCard"):PSTR("FlashFS"));
+ WSContentSend_P(UFS_FORM_FILE_UPGc1, WiFi.localIP().toString().c_str(), (ufs_dir == 1)?2:1, (ufs_dir == 1)?PSTR("SDCard"):PSTR("FlashFS"));
}
WSContentSend_P(UFS_FORM_FILE_UPGc2);
From 861c76bacaf294a88dc10eb185cec5885f7616a9 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 13 Jan 2021 12:38:35 +0100
Subject: [PATCH 41/71] Fix ESP32 reset 5,6 regression from yesterday
---
tasmota/support_esp32.ino | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino
index d56040b86..7bbad6468 100644
--- a/tasmota/support_esp32.ino
+++ b/tasmota/support_esp32.ino
@@ -144,24 +144,20 @@ void SettingsErase(uint8_t type) {
// main - Tasmota Settings data
int32_t r1, r2, r3;
switch (type) {
- case 0: // Reset 2, 5, 6 = Erase all flash from program end to end of physical flash
+ case 0: // Reset 2 = Erase all flash from program end to end of physical flash
+ case 2: // Reset 5, 6 = Erase all flash from program end to end of physical flash excluding filesystem
// nvs_flash_erase(); // Erase RTC, PHY, sta.mac, ap.sndchan, ap.mac, Tasmota etc.
r1 = NvmErase("qpc");
r2 = NvmErase("main");
r3 = TfsDeleteFile(TASM_FILE_SETTINGS);
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " Tasmota data (%d,%d,%d)"), r1, r2, r3);
break;
- case 1: case 4: // Reset 3 or WIFI_FORCE_RF_CAL_ERASE = SDK parameter area
+ case 1: // Reset 3 = SDK parameter area
+ case 4: // WIFI_FORCE_RF_CAL_ERASE = SDK parameter area
r1 = esp_phy_erase_cal_data_in_nvs();
// r1 = NvmErase("cal_data");
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " PHY data (%d)"), r1);
break;
- case 2: // Not used = QPC and Tasmota parameter area (0x0F3xxx - 0x0FBFFF)
- r1 = NvmErase("qpc");
- r2 = NvmErase("main");
- r3 = TfsDeleteFile(TASM_FILE_SETTINGS);
- AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " Tasmota data (%d,%d,%d)"), r1, r2, r3);
- break;
case 3: // QPC Reached = QPC, Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
// nvs_flash_erase(); // Erase RTC, PHY, sta.mac, ap.sndchan, ap.mac, Tasmota etc.
r1 = NvmErase("qpc");
From 8c46e439ca161ed48ddae701f37c2d4d107f3c51 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Wed, 13 Jan 2021 13:49:33 +0100
Subject: [PATCH 42/71] Support for download_fs.py
---
platformio.ini | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/platformio.ini b/platformio.ini
index e76901e33..a95530335 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -67,6 +67,7 @@ default_envs = ${build_envs.default_envs}
framework = arduino
board = esp01_1m
board_build.filesystem = littlefs
+custom_unpack_dir = unpacked_esp8266_littlefs
board_build.flash_mode = dout
board_build.ldscript = eagle.flash.1m.ld
@@ -77,7 +78,8 @@ build_flags = ${core.build_flags}
board_build.f_cpu = 80000000L
board_build.f_flash = 40000000L
-monitor_speed = 115200
+monitor_speed = 74880
+monitor_port = COM5
upload_speed = 115200
; *** Upload Serial reset method for Wemos and NodeMCU
upload_resetmethod = nodemcu
@@ -99,6 +101,7 @@ extra_scripts = pio-tools/strip-floats.py
pio-tools/name-firmware.py
pio-tools/gzip-firmware.py
pio-tools/override_copy.py
+ pio-tools/download_fs.py
[esp_defaults]
; *** remove undesired all warnings
From 988ca925dd4343934778ac0b5143bd142517e87c Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Wed, 13 Jan 2021 13:51:03 +0100
Subject: [PATCH 43/71] PIO file system downloader script
---
pio-tools/download_fs.py | 329 +++++++++++++++++++++++++++++++++++++++
1 file changed, 329 insertions(+)
create mode 100644 pio-tools/download_fs.py
diff --git a/pio-tools/download_fs.py b/pio-tools/download_fs.py
new file mode 100644
index 000000000..ed6426cc7
--- /dev/null
+++ b/pio-tools/download_fs.py
@@ -0,0 +1,329 @@
+# Written by Maximilian Gerhardt
+# 29th December 2020
+# License: Apache
+# Expanded from functionality provided by PlatformIO's espressif32 and espressif8266 platforms, credited below.
+# This script provides functions to download the filesystem (SPIFFS or LittleFS) from a running ESP32 / ESP8266
+# over the serial bootloader using esptool.py, and mklittlefs / mkspiffs for extracting.
+# run by either using the VSCode task "Custom" -> "Download Filesystem"
+# or by doing 'pio run -t downloadfs' (with optional '-e ') from the commandline.
+# output will be saved, by default, in the "unpacked_fs" of the project.
+# this folder can be changed by writing 'custom_unpack_dir = some_other_dir' in the corresponding platformio.ini
+# environment.
+import re
+import sys
+from os.path import isfile, join
+from enum import Enum
+import typing
+from platformio.builder.tools.pioupload import AutodetectUploadPort
+import os
+import subprocess
+import shutil
+
+Import("env")
+platform = env.PioPlatform()
+board = env.BoardConfig()
+mcu = board.get("build.mcu", "esp32")
+# needed for later
+AutodetectUploadPort(env)
+
+class FSType(Enum):
+ SPIFFS="spiffs"
+ LITTLEFS="littlefs"
+ FATFS="fatfs"
+
+class FSInfo:
+ def __init__(self, fs_type, start, length, page_size, block_size):
+ self.fs_type = fs_type
+ self.start = start
+ self.length = length
+ self.page_size = page_size
+ self.block_size = block_size
+ def __repr__(self):
+ return f"FS type {self.fs_type} Start {hex(self.start)} Len {self.length} Page size {self.page_size} Block size {self.block_size}"
+ # extract command supposed to be implemented by subclasses
+ def get_extract_cmd(self):
+ raise NotImplementedError()
+
+class LittleFSInfo(FSInfo):
+ def __init__(self, start, length, page_size, block_size):
+ if env["PIOPLATFORM"] == "espressif32":
+ #for ESP32: retrieve and evaluate, e.g. to mkspiffs_espressif32_arduino
+ self.tool = env.subst(env["MKSPIFFSTOOL"])
+ else:
+ self.tool = env["MKFSTOOL"] # from mkspiffs package
+ self.tool = join(platform.get_package_dir("tool-mklittlefs"), self.tool)
+ super().__init__(FSType.LITTLEFS, start, length, page_size, block_size)
+ def __repr__(self):
+ return f"FS type {self.fs_type} Start {hex(self.start)} Len {self.length} Page size {self.page_size} Block size {self.block_size} Tool: {self.tool}"
+ def get_extract_cmd(self, input_file, output_dir):
+ return f'"{self.tool}" -b {self.block_size} -p {self.page_size} --unpack "{output_dir}" "{input_file}"'
+
+
+class SPIFFSInfo(FSInfo):
+ def __init__(self, start, length, page_size, block_size):
+ if env["PIOPLATFORM"] == "espressif32":
+ #for ESP32: retrieve and evaluate, e.g. to mkspiffs_espressif32_arduino
+ self.tool = env.subst(env["MKSPIFFSTOOL"])
+ else:
+ self.tool = env["MKFSTOOL"] # from mkspiffs package
+ self.tool = join(platform.get_package_dir("tool-mkspiffs"), self.tool)
+ super().__init__(FSType.SPIFFS, start, length, page_size, block_size)
+ def __repr__(self):
+ return f"FS type {self.fs_type} Start {hex(self.start)} Len {self.length} Page size {self.page_size} Block size {self.block_size} Tool: {self.tool}"
+ def get_extract_cmd(self, input_file, output_dir):
+ return f'"{self.tool}" -b {self.block_size} -p {self.page_size} --unpack "{output_dir}" "{input_file}"'
+
+# SPIFFS helpers copied from ESP32, https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py
+# Copyright 2014-present PlatformIO
+# Licensed under the Apache License, Version 2.0 (the "License");
+
+def _parse_size(value):
+ if isinstance(value, int):
+ return value
+ elif value.isdigit():
+ return int(value)
+ elif value.startswith("0x"):
+ return int(value, 16)
+ elif value[-1].upper() in ("K", "M"):
+ base = 1024 if value[-1].upper() == "K" else 1024 * 1024
+ return int(value[:-1]) * base
+ return value
+
+def _parse_partitions(env):
+ partitions_csv = env.subst("$PARTITIONS_TABLE_CSV")
+ if not isfile(partitions_csv):
+ sys.stderr.write("Could not find the file %s with partitions "
+ "table.\n" % partitions_csv)
+ env.Exit(1)
+ return
+
+ result = []
+ next_offset = 0
+ with open(partitions_csv) as fp:
+ for line in fp.readlines():
+ line = line.strip()
+ if not line or line.startswith("#"):
+ continue
+ tokens = [t.strip() for t in line.split(",")]
+ if len(tokens) < 5:
+ continue
+ partition = {
+ "name": tokens[0],
+ "type": tokens[1],
+ "subtype": tokens[2],
+ "offset": tokens[3] or next_offset,
+ "size": tokens[4],
+ "flags": tokens[5] if len(tokens) > 5 else None
+ }
+ result.append(partition)
+ next_offset = (_parse_size(partition['offset']) +
+ _parse_size(partition['size']))
+ return result
+
+def esp32_fetch_spiffs_size(env):
+ spiffs = None
+ for p in _parse_partitions(env):
+ if p['type'] == "data" and p['subtype'] == "spiffs":
+ spiffs = p
+ if not spiffs:
+ sys.stderr.write(
+ env.subst("Could not find the `spiffs` section in the partitions "
+ "table $PARTITIONS_TABLE_CSV\n"))
+ env.Exit(1)
+ return
+ env["SPIFFS_START"] = _parse_size(spiffs['offset'])
+ env["SPIFFS_SIZE"] = _parse_size(spiffs['size'])
+ env["SPIFFS_PAGE"] = int("0x100", 16)
+ env["SPIFFS_BLOCK"] = int("0x1000", 16)
+
+## FS helpers for ESP8266
+# copied from https://github.com/platformio/platform-espressif8266/blob/develop/builder/main.py
+# Copyright 2014-present PlatformIO
+# Licensed under the Apache License, Version 2.0 (the "License");
+
+def _get_board_f_flash(env):
+ frequency = env.subst("$BOARD_F_FLASH")
+ frequency = str(frequency).replace("L", "")
+ return int(int(frequency) / 1000000)
+
+def _parse_ld_sizes(ldscript_path):
+ assert ldscript_path
+ result = {}
+ # get flash size from board's manifest
+ result['flash_size'] = int(env.BoardConfig().get("upload.maximum_size", 0))
+ # get flash size from LD script path
+ match = re.search(r"\.flash\.(\d+[mk]).*\.ld", ldscript_path)
+ if match:
+ result['flash_size'] = _parse_size(match.group(1))
+
+ appsize_re = re.compile(
+ r"irom0_0_seg\s*:.+len\s*=\s*(0x[\da-f]+)", flags=re.I)
+ filesystem_re = re.compile(
+ r"PROVIDE\s*\(\s*_%s_(\w+)\s*=\s*(0x[\da-f]+)\s*\)" % "FS"
+ if "arduino" in env.subst("$PIOFRAMEWORK")
+ else "SPIFFS",
+ flags=re.I,
+ )
+ with open(ldscript_path) as fp:
+ for line in fp.readlines():
+ line = line.strip()
+ if not line or line.startswith("/*"):
+ continue
+ match = appsize_re.search(line)
+ if match:
+ result['app_size'] = _parse_size(match.group(1))
+ continue
+ match = filesystem_re.search(line)
+ if match:
+ result['fs_%s' % match.group(1)] = _parse_size(
+ match.group(2))
+ return result
+
+def _get_flash_size(env):
+ ldsizes = _parse_ld_sizes(env.GetActualLDScript())
+ if ldsizes['flash_size'] < 1048576:
+ return "%dK" % (ldsizes['flash_size'] / 1024)
+ return "%dM" % (ldsizes['flash_size'] / 1048576)
+
+def esp8266_fetch_fs_size(env):
+ ldsizes = _parse_ld_sizes(env.GetActualLDScript())
+ for key in ldsizes:
+ if key.startswith("fs_"):
+ env[key.upper()] = ldsizes[key]
+
+ assert all([
+ k in env
+ for k in ["FS_START", "FS_END", "FS_PAGE", "FS_BLOCK"]
+ ])
+
+ # esptool flash starts from 0
+ for k in ("FS_START", "FS_END"):
+ _value = 0
+ if env[k] < 0x40300000:
+ _value = env[k] & 0xFFFFF
+ elif env[k] < 0x411FB000:
+ _value = env[k] & 0xFFFFFF
+ _value -= 0x200000 # correction
+ else:
+ _value = env[k] & 0xFFFFFF
+ _value += 0xE00000 # correction
+
+ env[k] = _value
+
+def esp8266_get_esptoolpy_reset_flags(resetmethod):
+ # no dtr, no_sync
+ resets = ("no_reset_no_sync", "soft_reset")
+ if resetmethod == "nodemcu":
+ # dtr
+ resets = ("default_reset", "hard_reset")
+ elif resetmethod == "ck":
+ # no dtr
+ resets = ("no_reset", "soft_reset")
+
+ return ["--before", resets[0], "--after", resets[1]]
+
+## Script interface functions
+
+def get_fs_type_start_and_length():
+ platform = env["PIOPLATFORM"]
+ if platform == "espressif32":
+ print("Retrieving filesystem info for ESP32. Assuming SPIFFS.")
+ print("Partition file: " + str(env.subst("$PARTITIONS_TABLE_CSV")))
+ esp32_fetch_spiffs_size(env)
+ return SPIFFSInfo(env["SPIFFS_START"], env["SPIFFS_SIZE"], env["SPIFFS_PAGE"], env["SPIFFS_BLOCK"])
+ elif platform == "espressif8266":
+ print("Retrieving filesystem info for ESP8266.")
+ filesystem = board.get("build.filesystem", "spiffs")
+ if filesystem not in ("spiffs", "littlefs"):
+ print("Unrecognized board_build.filesystem option '" + str(filesystem) + "'.")
+ env.Exit(1)
+ # fetching sizes is the same for all filesystems
+ esp8266_fetch_fs_size(env)
+ print("FS_START: " + hex(env["FS_START"]))
+ print("FS_END: " + hex(env["FS_END"]))
+ print("FS_PAGE: " + hex(env["FS_PAGE"]))
+ print("FS_BLOCK: " + hex(env["FS_BLOCK"]))
+ if filesystem == "spiffs":
+ print("Recognized SPIFFS filesystem.")
+ return SPIFFSInfo(env["FS_START"], env["FS_END"] - env["FS_START"], env["FS_PAGE"], env["FS_BLOCK"])
+ elif filesystem == "littlefs":
+ print("Recognized LittleFS filesystem.")
+ return LittleFSInfo(env["FS_START"], env["FS_END"] - env["FS_START"], env["FS_PAGE"], env["FS_BLOCK"])
+ else:
+ print("Unrecongized configuration.")
+ pass
+
+def download_fs(fs_info: FSInfo):
+ esptoolpy = join(platform.get_package_dir("tool-esptoolpy") or "", "esptool.py")
+ fs_file = join(env["PROJECT_DIR"], f"downloaded_fs_{hex(fs_info.start)}_{hex(fs_info.length)}.bin")
+ esptoolpy_flags = [
+ "--chip", mcu,
+ "--port", '"' + env.subst("$UPLOAD_PORT") + '"',
+ "--baud", env.subst("$UPLOAD_SPEED"),
+ "--before", "default_reset",
+ "--after", "hard_reset",
+ "read_flash",
+ hex(fs_info.start),
+ hex(fs_info.length),
+ '"' + fs_file + '"'
+ ]
+ esptoolpy_cmd = '"' + env["PYTHONEXE"]+ '"' + ' "' + esptoolpy + '" ' + " ".join(esptoolpy_flags)
+ print("Executing flash download command.")
+ print(esptoolpy_cmd)
+ try:
+ returncode = subprocess.call(esptoolpy_cmd, shell=False)
+ print("Downloaded filesystem binary.")
+ return (True, fs_file)
+ except subprocess.CalledProcessError as exc:
+ print("Downloading failed with " + str(exc))
+ return (False, "")
+
+def unpack_fs(fs_info: FSInfo, downloaded_file: str):
+ # by writing custom_unpack_dir = some_dir in the platformio.ini, one can
+ # control the unpack directory
+ unpack_dir = env.GetProjectOption("custom_unpack_dir", "unpacked_fs")
+ #unpack_dir = "unpacked_fs"
+ try:
+ if os.path.exists(unpack_dir):
+ shutil.rmtree(unpack_dir)
+ except Exception as exc:
+ print("Exception while attempting to remove the folder '" + str(unpack_dir) + "': " + str(exc))
+ if not os.path.exists(unpack_dir):
+ os.makedirs(unpack_dir)
+
+ cmd = fs_info.get_extract_cmd(downloaded_file, unpack_dir)
+ print("Executing extraction command: " + str(cmd))
+ try:
+ returncode = subprocess.call(cmd, shell=False)
+ print("Unpacked filesystem.")
+ return (True, unpack_dir)
+ except subprocess.CalledProcessError as exc:
+ print("Unpacking filesystem failed with " + str(exc))
+ return (False, "")
+
+def display_fs(extracted_dir):
+ # extract command already nicely lists all extracted files.
+ # no need to display that ourselves. just display a summary
+ file_count = sum([len(files) for r, d, files in os.walk(extracted_dir)])
+ print("Extracted " + str(file_count) + " file(s) from filesystem.")
+
+def command_download_fs(*args, **kwargs):
+ print("Entrypoint")
+ #print(env.Dump())
+ info = get_fs_type_start_and_length()
+ print("Parsed FS info: " + str(info))
+ download_ok, downloaded_file = download_fs(info)
+ print("Download was okay: " + str(download_ok) + ". File at: "+ str(downloaded_file))
+ unpack_ok, unpacked_dir = unpack_fs(info, downloaded_file)
+ if unpack_ok is True:
+ display_fs(unpacked_dir)
+
+env.AddCustomTarget(
+ name="downloadfs",
+ dependencies=None,
+ actions=[
+ command_download_fs
+ ],
+ title="Download Filesystem",
+ description="Downloads and displays files stored in the target ESP32/ESP8266"
+)
\ No newline at end of file
From a21acebdb447ec29a2a720df133ae4012ca3e846 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 13 Jan 2021 13:51:49 +0100
Subject: [PATCH 44/71] Add support for Last Known Good Settings
---
tasmota/settings.ino | 16 ++++++++++++----
tasmota/support_tasmota.ino | 9 +++++++++
tasmota/tasmota_globals.h | 5 +++--
3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/tasmota/settings.ino b/tasmota/settings.ino
index d61f66743..b2d438df6 100644
--- a/tasmota/settings.ino
+++ b/tasmota/settings.ino
@@ -540,7 +540,7 @@ void SettingsSave(uint8_t rotate)
#ifdef ESP8266
#ifdef USE_UFILESYS
TfsSaveFile(TASM_FILE_SETTINGS, (const uint8_t*)&Settings, sizeof(Settings));
-#endif
+#endif // USE_UFILESYS
if (ESP.flashEraseSector(settings_location)) {
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
}
@@ -578,7 +578,7 @@ void SettingsLoad(void) {
flash_location = 1;
slot = 0;
}
-#endif
+#endif // USE_UFILESYS
while (slot <= max_slots) { // Read all config pages in search of valid and latest
if (slot > 0) {
flash_location = (1 == slot) ? FLASH_EEPROM_START : (2 == slot) ? SETTINGS_LOCATION : flash_location -1;
@@ -602,7 +602,7 @@ void SettingsLoad(void) {
TfsLoadFile(TASM_FILE_SETTINGS, (uint8_t*)&Settings, sizeof(Settings));
AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded from File, " D_COUNT " %lu"), Settings.save_flag);
} else
-#endif
+#endif // USE_UFILESYS
{
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
@@ -617,7 +617,15 @@ void SettingsLoad(void) {
#ifndef FIRMWARE_MINIMAL
if ((0 == settings_location) || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h
- SettingsDefault();
+#ifdef USE_UFILESYS
+ if (TfsLoadFile(TASM_FILE_SETTINGS_LKG, (uint8_t*)&Settings, sizeof(Settings)) && (Settings.cfg_crc32 == GetSettingsCrc32())) {
+ settings_location = 1;
+ AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded from LKG File, " D_COUNT " %lu"), Settings.save_flag);
+ } else
+#endif // USE_UFILESYS
+ {
+ SettingsDefault();
+ }
}
settings_crc32 = GetSettingsCrc32();
#endif // FIRMWARE_MINIMAL
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index a6e0b2104..3ac17a490 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -886,6 +886,15 @@ void PerformEverySecond(void)
ESP_getSketchSize(); // Init sketchsize as it can take up to 2 seconds
}
#endif
+
+#ifdef USE_UFILESYS
+ static bool settings_lkg = false; // Settings saved as Last Known Good
+ // Copy Settings as Last Known Good if no changes have been saved since 30 minutes
+ if (!settings_lkg && (UtcTime() > START_VALID_TIME) && (Settings.cfg_timestamp < UtcTime() - (30 * 60))) {
+ TfsSaveFile(TASM_FILE_SETTINGS_LKG, (const uint8_t*)&Settings, sizeof(Settings));
+ settings_lkg = true;
+ }
+#endif
}
/*-------------------------------------------------------------------------------------------*\
diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h
index 330a1a87e..4524410dd 100644
--- a/tasmota/tasmota_globals.h
+++ b/tasmota/tasmota_globals.h
@@ -225,8 +225,9 @@ const uint16_t LOG_BUFFER_SIZE = 4000; // Max number of characters in lo
#error "Arduino ESP8266 Core versions before 2.7.1 are not supported"
#endif
-#define TASM_FILE_SETTINGS "/.settings"
-#define TASM_FILE_ZIGBEE "/zb"
+#define TASM_FILE_SETTINGS "/.settings" // Settings binary blob
+#define TASM_FILE_SETTINGS_LKG "/.settings.lkg" // Last Known Good Settings binary blob
+#define TASM_FILE_ZIGBEE "/zb" // Zigbee settings blob as used by CC2530 on ESP32
#ifndef MQTT_MAX_PACKET_SIZE
#define MQTT_MAX_PACKET_SIZE 1200 // Bytes
From 669aa6a45ac6e19bc9b184e8c569ee418ddacd8b Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Wed, 13 Jan 2021 13:52:32 +0100
Subject: [PATCH 45/71] fix copy&paste
---
platformio_override_sample.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index 3b82447f2..d82b7f45d 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -144,7 +144,7 @@ lib_extra_dirs = ${library.lib_extra_dirs}
[core32_stage]
-platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/tag/1.0.5-rc6
+platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/1.0.5-rc6/esp32-1.0.5-rc6.zip
platformio/tool-mklittlefs @ ~1.203.200522
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags}
From 3810251658a29c41856e409f000764309e32a621 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 13 Jan 2021 14:18:39 +0100
Subject: [PATCH 46/71] Update support_esptool.ino
---
tasmota/support_esptool.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/support_esptool.ino b/tasmota/support_esptool.ino
index 6551c7912..a066838af 100644
--- a/tasmota/support_esptool.ino
+++ b/tasmota/support_esptool.ino
@@ -95,7 +95,7 @@ bool EsptoolEraseSector(uint32_t sector)
void EsptoolErase(uint32_t start_sector, uint32_t end_sector)
{
- AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " from 0x%06X to 0x%06X"), start_sector * SPI_FLASH_SEC_SIZE, (end_sector * SPI_FLASH_SEC_SIZE) -1);
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " from 0x%08X to 0x%08X"), start_sector * SPI_FLASH_SEC_SIZE, (end_sector * SPI_FLASH_SEC_SIZE) -1);
int next_erase_sector = start_sector;
int remaining_erase_sector = end_sector - start_sector;
From 40007bbae991366f8b6f0b89ffd81eaff4801295 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 13 Jan 2021 15:54:43 +0100
Subject: [PATCH 47/71] Add WIFI_NONE_SLEEP when sleep = 0 and SO60 = 0
---
tasmota/support_wifi.ino | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino
index 845e115e6..95380cd74 100644
--- a/tasmota/support_wifi.ino
+++ b/tasmota/support_wifi.ino
@@ -153,11 +153,22 @@ void WiFiSetSleepMode(void)
*/
// Sleep explanation: https://github.com/esp8266/Arduino/blob/3f0c601cfe81439ce17e9bd5d28994a7ed144482/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L255
+/*
if (TasmotaGlobal.sleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
} else {
WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default)
}
+*/
+ if (TasmotaGlobal.sleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
+ WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
+ } else {
+ if (0 == TasmotaGlobal.sleep) {
+ WiFi.setSleepMode(WIFI_NONE_SLEEP); // Disable sleep
+ } else {
+ WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Sleep (Esp8288/Arduino core and sdk default)
+ }
+ }
WifiSetOutputPower();
}
From fa4326b6b0eac4a119577f5d2bb1c0d0af147c98 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 13 Jan 2021 16:57:04 +0100
Subject: [PATCH 48/71] Fix ESP32 compilation
---
tasmota/support_wifi.ino | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino
index 95380cd74..b281b0c51 100644
--- a/tasmota/support_wifi.ino
+++ b/tasmota/support_wifi.ino
@@ -163,9 +163,12 @@ void WiFiSetSleepMode(void)
if (TasmotaGlobal.sleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
} else {
+#ifdef ESP8266
if (0 == TasmotaGlobal.sleep) {
WiFi.setSleepMode(WIFI_NONE_SLEEP); // Disable sleep
- } else {
+ } else
+#endif
+ {
WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Sleep (Esp8288/Arduino core and sdk default)
}
}
From fdbd1dcc0ab98042c6d4dbc14308450d29eefa19 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 14 Jan 2021 17:03:01 +0100
Subject: [PATCH 49/71] Changed command ``Sleep 0``
Changed command ``Sleep 0`` removes any sleep from wifi modem except when ESP32 BLE is active
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/support_command.ino | 5 ++--
tasmota/support_wifi.ino | 15 +++++------
tasmota/tasmota.ino | 1 +
tasmota/xsns_52_ibeacon.ino | 11 +++-----
tasmota/xsns_62_MI_ESP32.ino | 51 +++++++++++++++++-------------------
7 files changed, 41 insertions(+), 44 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c4eb29802..e7e207f17 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Force initial default state ``SetOption57 1`` to scan wifi network every 44 minutes for strongest signal (#10395)
+- Command ``Sleep 0`` removes any sleep from wifi modem except when ESP32 BLE is active
## [9.2.0.2] 20210105
### Added
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 5981c4022..b3f8e38a0 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -96,6 +96,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
- Replaced RA8876 GPIO selection from ``SPI CS`` by ``RA8876 CS``
### Changed
+- Command ``Sleep 0`` removes any sleep from wifi modem except when ESP32 BLE is active
- Logging from heap to stack freeing 700 bytes RAM
- Disabled ``USE_LIGHT`` light support for ZBBridge saving 17.6kB [#10374](https://github.com/arendst/Tasmota/issues/10374)
- Force initial default state ``SetOption57 1`` to scan wifi network every 44 minutes for strongest signal [#10395](https://github.com/arendst/Tasmota/issues/10395)
diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino
index 0866d3f84..1c5e32474 100644
--- a/tasmota/support_command.ino
+++ b/tasmota/support_command.ino
@@ -967,8 +967,9 @@ void CmndSetoption(void)
bitWrite(Settings.flag5.data, pindex, XdrvMailbox.payload);
switch (pindex) {
case 1: // SetOption115 - Enable ESP32 MI32
- Settings.flag3.sleep_normal = 1; // SetOption60 - Enable normal sleep instead of dynamic sleep
- TasmotaGlobal.restart_flag = 2;
+ if (0 == XdrvMailbox.payload) {
+ TasmotaGlobal.restart_flag = 2;
+ }
break;
}
}
diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino
index b281b0c51..2b5101174 100644
--- a/tasmota/support_wifi.ino
+++ b/tasmota/support_wifi.ino
@@ -160,15 +160,14 @@ void WiFiSetSleepMode(void)
WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default)
}
*/
- if (TasmotaGlobal.sleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
- WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
- } else {
-#ifdef ESP8266
- if (0 == TasmotaGlobal.sleep) {
+ if (0 == TasmotaGlobal.sleep) {
+ if (!TasmotaGlobal.wifi_stay_asleep) {
WiFi.setSleepMode(WIFI_NONE_SLEEP); // Disable sleep
- } else
-#endif
- {
+ }
+ } else {
+ if (Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
+ WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
+ } else {
WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Sleep (Esp8288/Arduino core and sdk default)
}
}
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 36511aa9e..2407e61b1 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -125,6 +125,7 @@ struct {
bool skip_light_fade; // Temporarily skip light fading
bool restart_halt; // Do not restart but stay in wait loop
bool module_changed; // Indicate module changed since last restart
+ bool wifi_stay_asleep; // Allow sleep only incase of ESP32 BLE
StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits)
uint8_t spi_enabled; // SPI configured
diff --git a/tasmota/xsns_52_ibeacon.ino b/tasmota/xsns_52_ibeacon.ino
index 731189827..723446700 100755
--- a/tasmota/xsns_52_ibeacon.ino
+++ b/tasmota/xsns_52_ibeacon.ino
@@ -279,16 +279,13 @@ void ESP32Init() {
if (TasmotaGlobal.global_state.wifi_down) { return; }
+ TasmotaGlobal.wifi_stay_asleep = true;
if (WiFi.getSleep() == false) {
- if (0 == Settings.flag3.sleep_normal) {
- AddLog_P(LOG_LEVEL_DEBUG,PSTR("%s: About to restart to put WiFi modem in sleep mode"),"BLE");
- Settings.flag3.sleep_normal = 1; // SetOption60 - Enable normal sleep instead of dynamic sleep
- TasmotaGlobal.restart_flag = 2;
- }
- return;
+ AddLog_P(LOG_LEVEL_DEBUG,PSTR("%s: Put WiFi modem in sleep mode"),"BLE");
+ WiFi.setSleep(true); // Sleep
}
- AddLog_P(LOG_LEVEL_DEBUG,PSTR("%s: Initializing Blueetooth..."),"BLE");
+ AddLog_P(LOG_LEVEL_DEBUG,PSTR("%s: Initializing Bluetooth..."),"BLE");
if (!ESP32BLE.mode.init) {
NimBLEDevice::init("");
diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino
index 9e9c70dc5..689b5a72a 100644
--- a/tasmota/xsns_62_MI_ESP32.ino
+++ b/tasmota/xsns_62_MI_ESP32.ino
@@ -589,17 +589,17 @@ int MI32_decryptPacket(char *_buf, uint16_t _bufSize, uint32_t _type){
MI32_ReverseMAC(packet->MAC);
uint8_t _bindkey[16] = {0x0};
bool foundNoKey = true;
- AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: search key for MAC: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]);
+ AddLog_P(LOG_LEVEL_DEBUG,PSTR("M32: Search key for MAC: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]);
for(uint32_t i=0; iMAC,MIBLEbindKeys[i].MAC,sizeof(packet->MAC))==0){
memcpy(_bindkey,MIBLEbindKeys[i].key,sizeof(_bindkey));
- AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: decryption Key found"));
+ AddLog_P(LOG_LEVEL_DEBUG,PSTR("M32: Decryption Key found"));
foundNoKey = false;
break;
}
}
if(foundNoKey){
- AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: no Key found !!"));
+ AddLog_P(LOG_LEVEL_DEBUG,PSTR("M32: No Key found !!"));
return -2;
}
@@ -619,7 +619,7 @@ int MI32_decryptPacket(char *_buf, uint16_t _bufSize, uint32_t _type){
ret = br_ccm_check_tag(&ctx, &tag);
- AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, packet->payload[1],packet->payload[2],packet->payload[3],packet->payload[4],packet->payload[5]);
+ AddLog_P(LOG_LEVEL_DEBUG,PSTR("M32: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, packet->payload[1],packet->payload[2],packet->payload[3],packet->payload[4],packet->payload[5]);
return ret-1;
}
#endif // USE_MI_DECRYPTION
@@ -660,7 +660,7 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter)
bool _success = false;
for (uint32_t i=0;i19) {
- AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: Scan buffer full"));
+ AddLog_P(LOG_LEVEL_INFO,PSTR("M32: Scan buffer full"));
MI32.state.beaconScanCounter = 1;
return;
}
for(auto _scanResult : MIBLEscanResult){
if(memcmp(addr,_scanResult.MAC,6)==0){
- // AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: known device"));
+ // AddLog_P(LOG_LEVEL_INFO,PSTR("M32: known device"));
return;
}
}
@@ -1585,12 +1582,12 @@ void MI32addBeacon(uint8_t index, char* data){
_new.time = 0;
if(memcmp(_empty,_new.MAC,6) == 0){
_new.active = false;
- AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: beacon%u deactivated"), index);
+ AddLog_P(LOG_LEVEL_INFO,PSTR("M32: Beacon%u deactivated"), index);
}
else{
_new.active = true;
MI32.mode.activeBeacon = 1;
- AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: beacon added with MAC: %s"), _MAC);
+ AddLog_P(LOG_LEVEL_INFO,PSTR("M32: Beacon added with MAC: %s"), _MAC);
}
}
@@ -1845,7 +1842,7 @@ void CmndMi32Time(void) {
if (XdrvMailbox.data_len > 0) {
if (MIBLEsensors.size() > XdrvMailbox.payload) {
if ((LYWSD02 == MIBLEsensors[XdrvMailbox.payload].type) || (MHOC303 == MIBLEsensors[XdrvMailbox.payload].type)) {
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("MI32: will set Time"));
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR("M32: Will set Time"));
MI32.state.sensor = XdrvMailbox.payload;
MI32.mode.canScan = 0;
MI32.mode.canConnect = 0;
@@ -1875,7 +1872,7 @@ void CmndMi32Unit(void) {
if (XdrvMailbox.data_len > 0) {
if (MIBLEsensors.size() > XdrvMailbox.payload) {
if ((LYWSD02 == MIBLEsensors[XdrvMailbox.payload].type) || (MHOC303 == MIBLEsensors[XdrvMailbox.payload].type)) {
- AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: will set Unit"));
+ AddLog_P(LOG_LEVEL_DEBUG,PSTR("M32: Will set Unit"));
MI32.state.sensor = XdrvMailbox.payload;
MI32.mode.canScan = 0;
MI32.mode.canConnect = 0;
@@ -1925,11 +1922,11 @@ void CmndMi32Block(void){
switch (XdrvMailbox.index) {
case 0:
MIBLEBlockList.clear();
- // AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: size of ilist: %u"), MIBLEBlockList.size());
- ResponseCmndIdxChar(PSTR("block list cleared"));
+ // AddLog_P(LOG_LEVEL_INFO,PSTR("M32: Size of ilist: %u"), MIBLEBlockList.size());
+ ResponseCmndIdxChar(PSTR("Block list cleared"));
break;
case 1:
- ResponseCmndIdxChar(PSTR("show block list"));
+ ResponseCmndIdxChar(PSTR("Show block list"));
break;
}
}
@@ -1955,7 +1952,7 @@ void CmndMi32Block(void){
ResponseCmndIdxChar(XdrvMailbox.data);
MI32removeMIBLEsensor(_MACasBytes.buf);
}
- // AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: size of ilist: %u"), MIBLEBlockList.size());
+ // AddLog_P(LOG_LEVEL_INFO,PSTR("M32: Size of ilist: %u"), MIBLEBlockList.size());
break;
}
}
From e891c4e4901025a381454df76ebe1107b90f7972 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 14 Jan 2021 17:04:54 +0100
Subject: [PATCH 50/71] Update setSleepMode
---
.../ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp | 31 +++++++------------
.../ESP32-to-ESP8266-compat/src/ESP8266WiFi.h | 1 +
2 files changed, 12 insertions(+), 20 deletions(-)
diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp
index 0e26883ba..9f932040c 100644
--- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp
+++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp
@@ -28,14 +28,12 @@
#undef WiFi
#endif
-void WiFiClass32::setSleepMode(int iSleepMode)
-{
- // WIFI_MODEM_SLEEP
- WiFi.setSleep(iSleepMode != WIFI_MODEM_SLEEP);
+void WiFiClass32::setSleepMode(int iSleepMode) {
+ // WIFI_LIGHT_SLEEP and WIFI_MODEM_SLEEP
+ WiFi.setSleep(iSleepMode != WIFI_NONE_SLEEP);
}
-int WiFiClass32::getPhyMode()
-{
+int WiFiClass32::getPhyMode() {
int phy_mode = 0; // " BGNL"
uint8_t protocol_bitmap;
if (esp_wifi_get_protocol(WIFI_IF_STA, &protocol_bitmap) == ESP_OK) {
@@ -47,12 +45,10 @@ int WiFiClass32::getPhyMode()
return phy_mode;
}
-void WiFiClass32::wps_disable()
-{
+void WiFiClass32::wps_disable() {
}
-void WiFiClass32::setOutputPower(int n)
-{
+void WiFiClass32::setOutputPower(int n) {
wifi_power_t p = WIFI_POWER_2dBm;
if (n > 19)
p = WIFI_POWER_19_5dBm;
@@ -75,28 +71,23 @@ void WiFiClass32::setOutputPower(int n)
WiFi.setTxPower(p);
}
-void WiFiClass32::forceSleepBegin()
-{
+void WiFiClass32::forceSleepBegin() {
}
-void WiFiClass32::forceSleepWake()
-{
+void WiFiClass32::forceSleepWake() {
}
-bool WiFiClass32::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel, bool &hidden_scan)
-{
+bool WiFiClass32::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel, bool &hidden_scan) {
hidden_scan = false;
return WiFi.getNetworkInfo(i, ssid, encType, rssi, bssid, channel);
}
-void wifi_station_disconnect()
-{
+void wifi_station_disconnect() {
// erase ap: empty ssid, ...
WiFi.disconnect(true, true);
}
-void wifi_station_dhcpc_start()
-{
+void wifi_station_dhcpc_start() {
}
WiFiClass32 WiFi32;
diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h
index 9649f49f5..4a7c3ccc9 100644
--- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h
+++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h
@@ -28,6 +28,7 @@
#define ENC_TYPE_TKIP WIFI_AUTH_WPA_WPA2_PSK
#define ENC_TYPE_AUTO WIFI_AUTH_MAX + 1
+#define WIFI_NONE_SLEEP 0
#define WIFI_LIGHT_SLEEP 1
#define WIFI_MODEM_SLEEP 2
From d60b69a712fd4f741be6fcbffd233d756b53d01b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 14 Jan 2021 18:09:45 +0100
Subject: [PATCH 51/71] Try next NTP server on error
---
tasmota/support_wifi.ino | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino
index 2b5101174..f16a641fe 100644
--- a/tasmota/support_wifi.ino
+++ b/tasmota/support_wifi.ino
@@ -819,6 +819,8 @@ uint32_t WifiGetNtp(void) {
// Leap-Indicator: unknown (clock unsynchronized)
// See: https://github.com/letscontrolit/ESPEasy/issues/2886#issuecomment-586656384
AddLog_P(LOG_LEVEL_DEBUG, PSTR("NTP: IP %s unsynched"), time_server_ip.toString().c_str());
+ ntp_server_id++;
+ if (ntp_server_id > 2) { ntp_server_id = 0; } // Next server next time
return 0;
}
@@ -829,6 +831,8 @@ uint32_t WifiGetNtp(void) {
secs_since_1900 |= (uint32_t)packet_buffer[42] << 8;
secs_since_1900 |= (uint32_t)packet_buffer[43];
if (0 == secs_since_1900) { // No time stamp received
+ ntp_server_id++;
+ if (ntp_server_id > 2) { ntp_server_id = 0; } // Next server next time
return 0;
}
return secs_since_1900 - 2208988800UL;
From 339e78538795fe6fce1a1633fa4ad9f843ef51ba Mon Sep 17 00:00:00 2001
From: s-hadinger <49731213+s-hadinger@users.noreply.github.com>
Date: Thu, 14 Jan 2021 18:40:59 +0100
Subject: [PATCH 52/71] Fix Hue emulation for ESP32 (#10564)
* Fix Hue emulation for ESP32
* Fix compilation for Zigbee
Co-authored-by: Stephan Hadinger
---
tasmota/support_udp.ino | 31 ++++++++++++++-----------------
tasmota/xdrv_20_hue.ino | 2 --
tasmota/xdrv_21_wemo.ino | 2 --
tasmota/xdrv_21_wemo_multi.ino | 2 --
4 files changed, 14 insertions(+), 23 deletions(-)
diff --git a/tasmota/support_udp.ino b/tasmota/support_udp.ino
index 0462513d3..07aa6736e 100644
--- a/tasmota/support_udp.ino
+++ b/tasmota/support_udp.ino
@@ -32,7 +32,6 @@ IPAddress udp_remote_ip; // M-Search remote IP address
uint16_t udp_remote_port; // M-Search remote port
bool udp_connected = false;
-bool udp_response_mutex = false; // M-Search response mutex to control re-entry
#ifdef ESP8266
#ifndef UDP_MAX_PACKETS
@@ -89,14 +88,12 @@ bool UdpConnect(void)
if (UdpCtx.listen(&addr, 1900)) { // port 1900
// OK
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED));
- udp_response_mutex = false;
udp_connected = true;
}
#endif // ESP8266
#ifdef ESP32
if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), 1900)) {
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED));
- udp_response_mutex = false;
udp_connected = true;
#endif // ESP32
}
@@ -123,28 +120,29 @@ void PollUdp(void)
packet->buf[packet->len] = 0; // add NULL at the end of the packet
char * packet_buffer = (char*) &packet->buf;
int32_t len = packet->len;
+ AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d)"), len);
#endif // ESP8266
#ifdef ESP32
- while (PortUdp.parsePacket()) {
+ while (uint32_t pack_len = PortUdp.parsePacket()) {
char packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet
int32_t len = PortUdp.read(packet_buffer, UDP_BUFFER_SIZE -1);
packet_buffer[len] = 0;
+ PortUdp.flush();
+ AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d/%d)"), len, pack_len);
#endif // ESP32
- AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d)"), len);
+
// AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), packet_buffer);
// Simple Service Discovery Protocol (SSDP)
if (Settings.flag2.emulation) {
#if defined(USE_SCRIPT_HUE) || defined(USE_ZIGBEE)
- if (!udp_response_mutex && (strstr_P(packet_buffer, PSTR("M-SEARCH")) != nullptr)) {
+ if (TasmotaGlobal.devices_present && (strstr_P(packet_buffer, PSTR("M-SEARCH")) != nullptr)) {
#else
- if (TasmotaGlobal.devices_present && !udp_response_mutex && (strstr_P(packet_buffer, PSTR("M-SEARCH")) != nullptr)) {
+ if (TasmotaGlobal.devices_present && (strstr_P(packet_buffer, PSTR("M-SEARCH")) != nullptr)) {
#endif
if (0 == udp_last_received) {
udp_last_received = millis();
- udp_response_mutex = true;
-
#ifdef ESP8266
udp_remote_ip = packet->srcaddr;
udp_remote_port = packet->srcport;
@@ -159,35 +157,34 @@ void PollUdp(void)
LowerCase(packet_buffer, packet_buffer);
RemoveSpace(packet_buffer);
+ bool udp_proccessed = false; // make sure we process the packet only once
#ifdef USE_EMULATION_WEMO
- if (EMUL_WEMO == Settings.flag2.emulation) {
+ if (!udp_proccessed && (EMUL_WEMO == Settings.flag2.emulation)) {
if (strstr_P(packet_buffer, URN_BELKIN_DEVICE) != nullptr) { // type1 echo dot 2g, echo 1g's
WemoRespondToMSearch(1);
- return;
+ udp_proccessed = true;
}
else if ((strstr_P(packet_buffer, UPNP_ROOTDEVICE) != nullptr) || // type2 Echo 2g (echo & echo plus)
(strstr_P(packet_buffer, SSDPSEARCH_ALL) != nullptr) ||
(strstr_P(packet_buffer, SSDP_ALL) != nullptr)) {
WemoRespondToMSearch(2);
- return;
+ udp_proccessed = true;
}
}
#endif // USE_EMULATION_WEMO
#ifdef USE_EMULATION_HUE
- if (EMUL_HUE == Settings.flag2.emulation) {
+ if (!udp_proccessed && (EMUL_HUE == Settings.flag2.emulation)) {
+ AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: HUE"));
if ((strstr_P(packet_buffer, PSTR(":device:basic:1")) != nullptr) ||
(strstr_P(packet_buffer, UPNP_ROOTDEVICE) != nullptr) ||
(strstr_P(packet_buffer, SSDPSEARCH_ALL) != nullptr) ||
(strstr_P(packet_buffer, SSDP_ALL) != nullptr)) {
HueRespondToMSearch();
- return;
+ udp_proccessed = true;
}
}
#endif // USE_EMULATION_HUE
-
- udp_response_mutex = false;
- continue;
}
}
}
diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino
index 97eafbcba..4da625847 100644
--- a/tasmota/xdrv_20_hue.ino
+++ b/tasmota/xdrv_20_hue.ino
@@ -225,8 +225,6 @@ void HueRespondToMSearch(void)
// Do not use AddLog_P( here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP D_HUE " %s " D_TO " %s:%d"),
message, udp_remote_ip.toString().c_str(), udp_remote_port);
-
- udp_response_mutex = false;
}
/*********************************************************************************************\
diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino
index 96e937d21..18f793824 100644
--- a/tasmota/xdrv_21_wemo.ino
+++ b/tasmota/xdrv_21_wemo.ino
@@ -76,8 +76,6 @@ void WemoRespondToMSearch(int echo_type)
// Do not use AddLog_P( here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP D_WEMO " " D_JSON_TYPE " %d, %s " D_TO " %s:%d"),
echo_type, message, udp_remote_ip.toString().c_str(), udp_remote_port);
-
- udp_response_mutex = false;
}
/*********************************************************************************************\
diff --git a/tasmota/xdrv_21_wemo_multi.ino b/tasmota/xdrv_21_wemo_multi.ino
index ec3fb7d42..1a0b3ac6c 100644
--- a/tasmota/xdrv_21_wemo_multi.ino
+++ b/tasmota/xdrv_21_wemo_multi.ino
@@ -422,8 +422,6 @@ void WemoRespondToMSearch(int echo_type) {
for (uint32_t i = 0; i < numOfWemoSwitch; i++) {
wemoDevice[i]->WemoRespondToMSearch(echo_type);
}
-
- udp_response_mutex = false;
}
/*********************************************************************************************\
From f100ad5d032ac8ba9e974b959e6a406df30ca16a Mon Sep 17 00:00:00 2001
From: Erik Montnemery
Date: Thu, 14 Jan 2021 21:36:08 +0100
Subject: [PATCH 53/71] Include SetOption117 in discovery message
---
tasmota/xdrv_12_home_assistant.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino
index 8ef33c91f..bf4664886 100644
--- a/tasmota/xdrv_12_home_assistant.ino
+++ b/tasmota/xdrv_12_home_assistant.ino
@@ -197,7 +197,7 @@ const char HASS_DISCOVER_DEVICE[] PROGMEM = // Basic par
"\"tp\":[\"%s\",\"%s\",\"%s\"]," // Topics for command, stat and tele
"\"rl\":[%s],\"swc\":[%s],\"swn\":[%s],\"btn\":[%s]," // Inputs / Outputs
"\"so\":{\"4\":%d,\"11\":%d,\"13\":%d,\"17\":%d,\"20\":%d," // SetOptions
- "\"30\":%d,\"68\":%d,\"73\":%d,\"82\":%d,\"114\":%d},"
+ "\"30\":%d,\"68\":%d,\"73\":%d,\"82\":%d,\"114\":%d,\"117\":%d},"
"\"lk\":%d,\"lt_st\":%d,\"sho\":[%s],\"ver\":1}"; // Light SubType, Shutter Options and Discovery version
typedef struct HASS {
@@ -341,7 +341,7 @@ void NewHAssDiscovery(void)
TasmotaGlobal.version, TasmotaGlobal.mqtt_topic, SettingsText(SET_MQTT_FULLTOPIC), SUB_PREFIX, PUB_PREFIX, PUB_PREFIX2, Hass.RelLst, stemp3, stemp4,
stemp5, Settings.flag.mqtt_response, Settings.flag.button_swap, Settings.flag.button_single, Settings.flag.decimal_text, Settings.flag.not_power_linked,
Settings.flag.hass_light, Settings.flag3.pwm_multi_channels, Settings.flag3.mqtt_buttons, Settings.flag4.alexa_ct_range, Settings.flag5.mqtt_switches,
- light_controller.isCTRGBLinked(), Light.subtype, stemp6);
+ Settings.flag5.fade_fixed_duration, light_controller.isCTRGBLinked(), Light.subtype, stemp6);
}
MqttPublish(stopic, true);
From 46bf60ac1551ab3ccffeeb7fd76f65ab68f8ec48 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 15 Jan 2021 10:43:58 +0100
Subject: [PATCH 54/71] Small refactor NTP
---
tasmota/support_wifi.ino | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino
index f16a641fe..15f5e10c2 100644
--- a/tasmota/support_wifi.ino
+++ b/tasmota/support_wifi.ino
@@ -748,6 +748,7 @@ uint32_t WifiGetNtp(void) {
char* ntp_server;
bool resolved_ip = false;
for (uint32_t i = 0; i <= MAX_NTP_SERVERS; i++) {
+ if (ntp_server_id > 2) { ntp_server_id = 0; }
if (i < MAX_NTP_SERVERS) {
ntp_server = SettingsText(SET_NTPSERVER1 + ntp_server_id);
} else {
@@ -760,7 +761,6 @@ uint32_t WifiGetNtp(void) {
if (resolved_ip) { break; }
}
ntp_server_id++;
- if (ntp_server_id > 2) { ntp_server_id = 0; }
}
if (!resolved_ip) {
// AddLog_P(LOG_LEVEL_DEBUG, PSTR("NTP: No server found"));
@@ -798,8 +798,7 @@ uint32_t WifiGetNtp(void) {
packet_buffer[15] = 52;
if (udp.beginPacket(time_server_ip, 123) == 0) { // NTP requests are to port 123
- ntp_server_id++;
- if (ntp_server_id > 2) { ntp_server_id = 0; } // Next server next time
+ ntp_server_id++; // Next server next time
udp.stop();
return 0;
}
@@ -819,8 +818,7 @@ uint32_t WifiGetNtp(void) {
// Leap-Indicator: unknown (clock unsynchronized)
// See: https://github.com/letscontrolit/ESPEasy/issues/2886#issuecomment-586656384
AddLog_P(LOG_LEVEL_DEBUG, PSTR("NTP: IP %s unsynched"), time_server_ip.toString().c_str());
- ntp_server_id++;
- if (ntp_server_id > 2) { ntp_server_id = 0; } // Next server next time
+ ntp_server_id++; // Next server next time
return 0;
}
@@ -831,8 +829,7 @@ uint32_t WifiGetNtp(void) {
secs_since_1900 |= (uint32_t)packet_buffer[42] << 8;
secs_since_1900 |= (uint32_t)packet_buffer[43];
if (0 == secs_since_1900) { // No time stamp received
- ntp_server_id++;
- if (ntp_server_id > 2) { ntp_server_id = 0; } // Next server next time
+ ntp_server_id++; // Next server next time
return 0;
}
return secs_since_1900 - 2208988800UL;
@@ -842,6 +839,7 @@ uint32_t WifiGetNtp(void) {
// Timeout.
AddLog_P(LOG_LEVEL_DEBUG, PSTR("NTP: No reply"));
udp.stop();
+ ntp_server_id++; // Next server next time
return 0;
}
From d64a6a1b1081b821de9c456c74ba60ed3eebbfa4 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 15 Jan 2021 11:45:04 +0100
Subject: [PATCH 55/71] Increase sensor support
---
tasmota/xsns_interface.ino | 135 ++++++++++++++++++++++++++++++++++---
1 file changed, 125 insertions(+), 10 deletions(-)
diff --git a/tasmota/xsns_interface.ino b/tasmota/xsns_interface.ino
index 21918f22c..f41de7920 100644
--- a/tasmota/xsns_interface.ino
+++ b/tasmota/xsns_interface.ino
@@ -825,27 +825,144 @@ const uint8_t kXsnsList[] = {
#endif
#ifdef XSNS_99
- XSNS_99
+ XSNS_99,
#endif
+
+#ifdef XSNS_100
+ XSNS_100,
+#endif
+
+#ifdef XSNS_101
+ XSNS_101,
+#endif
+
+#ifdef XSNS_102
+ XSNS_102,
+#endif
+
+#ifdef XSNS_103
+ XSNS_103,
+#endif
+
+#ifdef XSNS_104
+ XSNS_104,
+#endif
+
+#ifdef XSNS_105
+ XSNS_105,
+#endif
+
+#ifdef XSNS_106
+ XSNS_106,
+#endif
+
+#ifdef XSNS_107
+ XSNS_107,
+#endif
+
+#ifdef XSNS_108
+ XSNS_108,
+#endif
+
+#ifdef XSNS_109
+ XSNS_109,
+#endif
+
+#ifdef XSNS_110
+ XSNS_110,
+#endif
+
+#ifdef XSNS_111
+ XSNS_111,
+#endif
+
+#ifdef XSNS_112
+ XSNS_112,
+#endif
+
+#ifdef XSNS_113
+ XSNS_113,
+#endif
+
+#ifdef XSNS_114
+ XSNS_114,
+#endif
+
+#ifdef XSNS_115
+ XSNS_115,
+#endif
+
+#ifdef XSNS_116
+ XSNS_116,
+#endif
+
+#ifdef XSNS_117
+ XSNS_117,
+#endif
+
+#ifdef XSNS_118
+ XSNS_118,
+#endif
+
+#ifdef XSNS_119
+ XSNS_119,
+#endif
+
+#ifdef XSNS_120
+ XSNS_120,
+#endif
+
+#ifdef XSNS_121
+ XSNS_121,
+#endif
+
+#ifdef XSNS_122
+ XSNS_122,
+#endif
+
+#ifdef XSNS_123
+ XSNS_123,
+#endif
+
+#ifdef XSNS_124
+ XSNS_124,
+#endif
+
+#ifdef XSNS_125
+ XSNS_125,
+#endif
+
+#ifdef XSNS_126
+ XSNS_126,
+#endif
+
+#ifdef XSNS_127
+ XSNS_127,
+#endif
+
+#ifdef XSNS_128
+ XSNS_128
+#endif
+
};
/*********************************************************************************************/
-bool XsnsEnabled(uint32_t sns_index)
-{
+bool XsnsEnabled(uint32_t sns_index) {
if (sns_index < sizeof(kXsnsList)) {
#ifdef XFUNC_PTR_IN_ROM
uint32_t index = pgm_read_byte(kXsnsList + sns_index);
#else
uint32_t index = kXsnsList[sns_index];
#endif
- return bitRead(Settings.sensors[index / 32], index % 32);
+ if (index < MAX_XSNS_DRIVERS) {
+ return bitRead(Settings.sensors[index / 32], index % 32);
+ }
}
return true;
}
-void XsnsSensorState(void)
-{
+void XsnsSensorState(void) {
ResponseAppend_P(PSTR("\"")); // Use string for enable/disable signal
for (uint32_t i = 0; i < sizeof(kXsnsList); i++) {
#ifdef XFUNC_PTR_IN_ROM
@@ -866,8 +983,7 @@ void XsnsSensorState(void)
* Function call to all xsns
\*********************************************************************************************/
-bool XsnsNextCall(uint8_t Function, uint8_t &xsns_index)
-{
+bool XsnsNextCall(uint8_t Function, uint8_t &xsns_index) {
if (0 == xsns_present) {
xsns_index = 0;
return false;
@@ -891,8 +1007,7 @@ bool XsnsNextCall(uint8_t Function, uint8_t &xsns_index)
return xsns_func_ptr[xsns_index](Function);
}
-bool XsnsCall(uint8_t Function)
-{
+bool XsnsCall(uint8_t Function) {
bool result = false;
DEBUG_TRACE_LOG(PSTR("SNS: %d"), Function);
From 2c9203d6625506eda3715c85a8805895239cac2d Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 15 Jan 2021 12:01:15 +0100
Subject: [PATCH 56/71] Increase driver and display support
---
tasmota/xdrv_interface.ino | 236 ++++++++++++++++++++++++++++++++++++-
tasmota/xdsp_interface.ino | 66 ++++++++++-
2 files changed, 299 insertions(+), 3 deletions(-)
diff --git a/tasmota/xdrv_interface.ino b/tasmota/xdrv_interface.ino
index a5e0f6479..77c93c6da 100644
--- a/tasmota/xdrv_interface.ino
+++ b/tasmota/xdrv_interface.ino
@@ -416,7 +416,123 @@ bool (* const xdrv_func_ptr[])(uint8_t) = { // Driver Function Pointers
#endif
#ifdef XDRV_99
- &Xdrv99
+ &Xdrv99,
+#endif
+
+#ifdef XDRV_100
+ &Xdrv100,
+#endif
+
+#ifdef XDRV_101
+ &Xdrv101,
+#endif
+
+#ifdef XDRV_102
+ &Xdrv102,
+#endif
+
+#ifdef XDRV_103
+ &Xdrv103,
+#endif
+
+#ifdef XDRV_104
+ &Xdrv104,
+#endif
+
+#ifdef XDRV_105
+ &Xdrv105,
+#endif
+
+#ifdef XDRV_106
+ &Xdrv106,
+#endif
+
+#ifdef XDRV_107
+ &Xdrv107,
+#endif
+
+#ifdef XDRV_108
+ &Xdrv108,
+#endif
+
+#ifdef XDRV_109
+ &Xdrv109,
+#endif
+
+#ifdef XDRV_110
+ &Xdrv110,
+#endif
+
+#ifdef XDRV_111
+ &Xdrv111,
+#endif
+
+#ifdef XDRV_112
+ &Xdrv112,
+#endif
+
+#ifdef XDRV_113
+ &Xdrv113,
+#endif
+
+#ifdef XDRV_114
+ &Xdrv114,
+#endif
+
+#ifdef XDRV_115
+ &Xdrv115,
+#endif
+
+#ifdef XDRV_116
+ &Xdrv116,
+#endif
+
+#ifdef XDRV_117
+ &Xdrv117,
+#endif
+
+#ifdef XDRV_118
+ &Xdrv118,
+#endif
+
+#ifdef XDRV_119
+ &Xdrv119,
+#endif
+
+#ifdef XDRV_120
+ &Xdrv120,
+#endif
+
+#ifdef XDRV_121
+ &Xdrv121,
+#endif
+
+#ifdef XDRV_122
+ &Xdrv122,
+#endif
+
+#ifdef XDRV_123
+ &Xdrv123,
+#endif
+
+#ifdef XDRV_124
+ &Xdrv124,
+#endif
+
+#ifdef XDRV_125
+ &Xdrv125,
+#endif
+
+#ifdef XDRV_126
+ &Xdrv126,
+#endif
+
+#ifdef XDRV_127
+ &Xdrv127,
+#endif
+
+#ifdef XDRV_128
+ &Xdrv128
#endif
};
@@ -825,7 +941,123 @@ const uint8_t kXdrvList[] = {
#endif
#ifdef XDRV_99
- XDRV_99
+ XDRV_99,
+#endif
+
+#ifdef XDRV_100
+ Xdrv100,
+#endif
+
+#ifdef XDRV_101
+ Xdrv101,
+#endif
+
+#ifdef XDRV_102
+ Xdrv102,
+#endif
+
+#ifdef XDRV_103
+ Xdrv103,
+#endif
+
+#ifdef XDRV_104
+ Xdrv104,
+#endif
+
+#ifdef XDRV_105
+ Xdrv105,
+#endif
+
+#ifdef XDRV_106
+ Xdrv106,
+#endif
+
+#ifdef XDRV_107
+ Xdrv107,
+#endif
+
+#ifdef XDRV_108
+ Xdrv108,
+#endif
+
+#ifdef XDRV_109
+ Xdrv109,
+#endif
+
+#ifdef XDRV_110
+ Xdrv110,
+#endif
+
+#ifdef XDRV_111
+ Xdrv111,
+#endif
+
+#ifdef XDRV_112
+ Xdrv112,
+#endif
+
+#ifdef XDRV_113
+ Xdrv113,
+#endif
+
+#ifdef XDRV_114
+ Xdrv114,
+#endif
+
+#ifdef XDRV_115
+ Xdrv115,
+#endif
+
+#ifdef XDRV_116
+ Xdrv116,
+#endif
+
+#ifdef XDRV_117
+ Xdrv117,
+#endif
+
+#ifdef XDRV_118
+ Xdrv118,
+#endif
+
+#ifdef XDRV_119
+ Xdrv119,
+#endif
+
+#ifdef XDRV_120
+ Xdrv120,
+#endif
+
+#ifdef XDRV_121
+ Xdrv121,
+#endif
+
+#ifdef XDRV_122
+ Xdrv122,
+#endif
+
+#ifdef XDRV_123
+ Xdrv123,
+#endif
+
+#ifdef XDRV_124
+ Xdrv124,
+#endif
+
+#ifdef XDRV_125
+ Xdrv125,
+#endif
+
+#ifdef XDRV_126
+ Xdrv126,
+#endif
+
+#ifdef XDRV_127
+ Xdrv127,
+#endif
+
+#ifdef XDRV_128
+ Xdrv128
#endif
};
diff --git a/tasmota/xdsp_interface.ino b/tasmota/xdsp_interface.ino
index 1ce18ff6c..3ca49f3d6 100644
--- a/tasmota/xdsp_interface.ino
+++ b/tasmota/xdsp_interface.ino
@@ -87,7 +87,71 @@ bool (* const xdsp_func_ptr[])(uint8_t) = { // Display Function Pointers
#endif
#ifdef XDSP_16
- &Xdsp16
+ &Xdsp16,
+#endif
+
+#ifdef XDSP_17
+ &Xdsp17,
+#endif
+
+#ifdef XDSP_18
+ &Xdsp18,
+#endif
+
+#ifdef XDSP_19
+ &Xdsp19,
+#endif
+
+#ifdef XDSP_20
+ &Xdsp20,
+#endif
+
+#ifdef XDSP_21
+ &Xdsp21,
+#endif
+
+#ifdef XDSP_22
+ &Xdsp22,
+#endif
+
+#ifdef XDSP_23
+ &Xdsp23,
+#endif
+
+#ifdef XDSP_24
+ &Xdsp24,
+#endif
+
+#ifdef XDSP_25
+ &Xdsp25,
+#endif
+
+#ifdef XDSP_26
+ &Xdsp26,
+#endif
+
+#ifdef XDSP_27
+ &Xdsp27,
+#endif
+
+#ifdef XDSP_28
+ &Xdsp28,
+#endif
+
+#ifdef XDSP_29
+ &Xdsp29,
+#endif
+
+#ifdef XDSP_30
+ &Xdsp30,
+#endif
+
+#ifdef XDSP_31
+ &Xdsp31,
+#endif
+
+#ifdef XDSP_32
+ &Xdsp32
#endif
};
From 89a9c049d6ae99cc478cbfeff8ba6c9064fced61 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 15 Jan 2021 14:31:25 +0100
Subject: [PATCH 57/71] Add debug message regarding energy reset
---
tasmota/xdrv_03_energy.ino | 1 +
1 file changed, 1 insertion(+)
diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino
index 7c7ba932e..f57431203 100644
--- a/tasmota/xdrv_03_energy.ino
+++ b/tasmota/xdrv_03_energy.ino
@@ -537,6 +537,7 @@ void EnergyEverySecond(void)
}
if (!data_valid) {
Energy.start_energy = 0;
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR("NRG: Energy reset by " STR(ENERGY_WATCHDOG) " seconds invalid data"));
XnrgCall(FUNC_ENERGY_RESET);
}
From 6a2016f56834ee21189a3a72343a621c8f98de6b Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 15 Jan 2021 15:09:49 +0100
Subject: [PATCH 58/71] Remove redundant entrys
---
platformio_override_sample.ini | 16 ++--------------
1 file changed, 2 insertions(+), 14 deletions(-)
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index d82b7f45d..e46754e7a 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -116,33 +116,21 @@ build_flags = ${esp82xx_defaults.build_flags}
-DWAVEFORM_LOCKED_PWM
-Wno-switch-unreachable
-
[common32]
-platform = ${core32.platform}
platform_packages = ${core32.platform_packages}
build_unflags = ${core32.build_unflags}
build_flags = ${core32.build_flags}
-board = esp32dev
-board_build.ldscript = esp32_out.ld
-board_build.partitions = esp32_partition_app1984k_spiffs64k.csv
-board_build.flash_mode = ${common.board_build.flash_mode}
-board_build.f_flash = ${common.board_build.f_flash}
-board_build.f_cpu = ${common.board_build.f_cpu}
-monitor_speed = ${common.monitor_speed}
-upload_port = ${common.upload_port}
-upload_resetmethod = ${common.upload_resetmethod}
-upload_speed = 921600
-extra_scripts = ${common.extra_scripts}
+upload_port = COM4
lib_extra_dirs = ${library.lib_extra_dirs}
; *** ESP32 lib. ALWAYS needed for ESP32 !!!
lib/libesp32
+
[core32]
; Activate Stage Core32 by removing ";" in next 3 lines, if you want to override the standard core32
;platform_packages = ${core32_stage.platform_packages}
;build_unflags = ${core32_stage.build_unflags}
;build_flags = ${core32_stage.build_flags}
-
[core32_stage]
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/1.0.5-rc6/esp32-1.0.5-rc6.zip
platformio/tool-mklittlefs @ ~1.203.200522
From 7fc0c42e0490ead2ec22bc4fc42c54d5dcaadb41 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 15 Jan 2021 15:15:04 +0100
Subject: [PATCH 59/71] change from string to list
and hack for using littlefs for ESP32 instead of SPIFFS
---
pio-tools/download_fs.py | 44 ++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/pio-tools/download_fs.py b/pio-tools/download_fs.py
index ed6426cc7..f43bec128 100644
--- a/pio-tools/download_fs.py
+++ b/pio-tools/download_fs.py
@@ -1,14 +1,14 @@
# Written by Maximilian Gerhardt
# 29th December 2020
# License: Apache
-# Expanded from functionality provided by PlatformIO's espressif32 and espressif8266 platforms, credited below.
-# This script provides functions to download the filesystem (SPIFFS or LittleFS) from a running ESP32 / ESP8266
+# Expanded from functionality provided by PlatformIO's espressif32 and espressif8266 platforms, credited below.
+# This script provides functions to download the filesystem (SPIFFS or LittleFS) from a running ESP32 / ESP8266
# over the serial bootloader using esptool.py, and mklittlefs / mkspiffs for extracting.
-# run by either using the VSCode task "Custom" -> "Download Filesystem"
-# or by doing 'pio run -t downloadfs' (with optional '-e ') from the commandline.
+# run by either using the VSCode task "Custom" -> "Download Filesystem"
+# or by doing 'pio run -t downloadfs' (with optional '-e ') from the commandline.
# output will be saved, by default, in the "unpacked_fs" of the project.
-# this folder can be changed by writing 'custom_unpack_dir = some_other_dir' in the corresponding platformio.ini
-# environment.
+# this folder can be changed by writing 'custom_unpack_dir = some_other_dir' in the corresponding platformio.ini
+# environment.
import re
import sys
from os.path import isfile, join
@@ -23,25 +23,29 @@ Import("env")
platform = env.PioPlatform()
board = env.BoardConfig()
mcu = board.get("build.mcu", "esp32")
+# Hack for using mklittlefs instead of mkspiffs -> needed since littlefs is not supported with this for ESP32
+#print("Replace MKSPIFFSTOOL with mklittlefs")
+env.Replace( MKSPIFFSTOOL=platform.get_package_dir("tool-mklittlefs") + '/mklittlefs' )
+
# needed for later
AutodetectUploadPort(env)
-class FSType(Enum):
+class FSType(Enum):
SPIFFS="spiffs"
LITTLEFS="littlefs"
- FATFS="fatfs"
+ FATFS="fatfs"
class FSInfo:
- def __init__(self, fs_type, start, length, page_size, block_size):
+ def __init__(self, fs_type, start, length, page_size, block_size):
self.fs_type = fs_type
- self.start = start
+ self.start = start
self.length = length
self.page_size = page_size
self.block_size = block_size
def __repr__(self):
return f"FS type {self.fs_type} Start {hex(self.start)} Len {self.length} Page size {self.page_size} Block size {self.block_size}"
# extract command supposed to be implemented by subclasses
- def get_extract_cmd(self):
+ def get_extract_cmd(self, input_file, output_dir):
raise NotImplementedError()
class LittleFSInfo(FSInfo):
@@ -53,10 +57,10 @@ class LittleFSInfo(FSInfo):
self.tool = env["MKFSTOOL"] # from mkspiffs package
self.tool = join(platform.get_package_dir("tool-mklittlefs"), self.tool)
super().__init__(FSType.LITTLEFS, start, length, page_size, block_size)
- def __repr__(self):
+ def __repr__(self):
return f"FS type {self.fs_type} Start {hex(self.start)} Len {self.length} Page size {self.page_size} Block size {self.block_size} Tool: {self.tool}"
def get_extract_cmd(self, input_file, output_dir):
- return f'"{self.tool}" -b {self.block_size} -p {self.page_size} --unpack "{output_dir}" "{input_file}"'
+ return [self.tool, "-b", str(self.block_size), "-p", str(self.page_size), "--unpack", output_dir, input_file]
class SPIFFSInfo(FSInfo):
@@ -68,7 +72,7 @@ class SPIFFSInfo(FSInfo):
self.tool = env["MKFSTOOL"] # from mkspiffs package
self.tool = join(platform.get_package_dir("tool-mkspiffs"), self.tool)
super().__init__(FSType.SPIFFS, start, length, page_size, block_size)
- def __repr__(self):
+ def __repr__(self):
return f"FS type {self.fs_type} Start {hex(self.start)} Len {self.length} Page size {self.page_size} Block size {self.block_size} Tool: {self.tool}"
def get_extract_cmd(self, input_file, output_dir):
return f'"{self.tool}" -b {self.block_size} -p {self.page_size} --unpack "{output_dir}" "{input_file}"'
@@ -258,16 +262,16 @@ def download_fs(fs_info: FSInfo):
fs_file = join(env["PROJECT_DIR"], f"downloaded_fs_{hex(fs_info.start)}_{hex(fs_info.length)}.bin")
esptoolpy_flags = [
"--chip", mcu,
- "--port", '"' + env.subst("$UPLOAD_PORT") + '"',
+ "--port", env.subst("$UPLOAD_PORT"),
"--baud", env.subst("$UPLOAD_SPEED"),
"--before", "default_reset",
"--after", "hard_reset",
- "read_flash",
+ "read_flash",
hex(fs_info.start),
hex(fs_info.length),
- '"' + fs_file + '"'
+ fs_file
]
- esptoolpy_cmd = '"' + env["PYTHONEXE"]+ '"' + ' "' + esptoolpy + '" ' + " ".join(esptoolpy_flags)
+ esptoolpy_cmd = [env["PYTHONEXE"], esptoolpy] + esptoolpy_flags
print("Executing flash download command.")
print(esptoolpy_cmd)
try:
@@ -302,7 +306,7 @@ def unpack_fs(fs_info: FSInfo, downloaded_file: str):
return (False, "")
def display_fs(extracted_dir):
- # extract command already nicely lists all extracted files.
+ # extract command already nicely lists all extracted files.
# no need to display that ourselves. just display a summary
file_count = sum([len(files) for r, d, files in os.walk(extracted_dir)])
print("Extracted " + str(file_count) + " file(s) from filesystem.")
@@ -326,4 +330,4 @@ env.AddCustomTarget(
],
title="Download Filesystem",
description="Downloads and displays files stored in the target ESP32/ESP8266"
-)
\ No newline at end of file
+)
From a16306fbf6c7b61d7be8ac5b27040c22c1f0fd96 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 15 Jan 2021 15:16:41 +0100
Subject: [PATCH 60/71] add custom_unpack_dir
---
platformio_tasmota32.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini
index 79c56eb96..a41222bb4 100644
--- a/platformio_tasmota32.ini
+++ b/platformio_tasmota32.ini
@@ -48,6 +48,7 @@ build_unflags = ${core32.build_unflags}
build_flags = ${core32.build_flags}
board = esp32dev
board_build.filesystem = ${common.board_build.filesystem}
+custom_unpack_dir = ${common.custom_unpack_dir}
board_build.ldscript = esp32_out.ld
board_build.partitions = esp32_partition_app1984k_spiffs64k.csv
board_build.flash_mode = ${common.board_build.flash_mode}
From 129af59a9db58dc9b57506d62cd786262ed912df Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 15 Jan 2021 15:19:01 +0100
Subject: [PATCH 61/71] change unpack_dir
---
platformio.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio.ini b/platformio.ini
index a95530335..12ccfcc90 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -67,7 +67,7 @@ default_envs = ${build_envs.default_envs}
framework = arduino
board = esp01_1m
board_build.filesystem = littlefs
-custom_unpack_dir = unpacked_esp8266_littlefs
+custom_unpack_dir = unpacked_littlefs
board_build.flash_mode = dout
board_build.ldscript = eagle.flash.1m.ld
From c74cce1c4e9d3c8b1866dfe7342e2fdb7392dfe9 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 15 Jan 2021 15:20:39 +0100
Subject: [PATCH 62/71] add filesystems directorys
---
.gitignore | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitignore b/.gitignore
index 96c63651b..503ccf780 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,8 @@
.clang_complete
.gcc-flags.json
.cache
+data
+unpacked_fs
tasmota/user_config_override.h
build
build_output
From 43fd9ee1f23f742cf84162cef81f40a3fe4447cc Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 15 Jan 2021 16:17:25 +0100
Subject: [PATCH 63/71] Fix dual filesystem commands
---
tasmota/xdrv_50_filesystem.ino | 71 +++++++++++++++++++++-------------
1 file changed, 45 insertions(+), 26 deletions(-)
diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino
index 8066a9b93..0b7fc53d2 100644
--- a/tasmota/xdrv_50_filesystem.ino
+++ b/tasmota/xdrv_50_filesystem.ino
@@ -72,25 +72,28 @@ ufsfree free size in kB
#include "FS.h"
#endif // ESP32
-// global file system pointer
+// Global file system pointer
FS *ufsp;
-// flash file system pointer on esp32
+// Flash file system pointer
FS *ffsp;
-// local pointer for file managment
+// Local pointer for file managment
FS *dfsp;
char ufs_path[48];
File ufs_upload_file;
uint8_t ufs_dir;
-// 0 = none, 1 = SD, 2 = ffat, 3 = littlefs
+// 0 = None, 1 = SD, 2 = ffat, 3 = littlefs
uint8_t ufs_type;
uint8_t ffs_type;
bool download_busy;
+
+
+
/*********************************************************************************************/
-// init flash file system
+// Init flash file system
void UfsInitOnce(void) {
ufs_type = 0;
ffsp = 0;
@@ -130,21 +133,13 @@ void UfsInitOnce(void) {
void UfsInit(void) {
UfsInitOnce();
if (ufs_type) {
- AddLog_P(LOG_LEVEL_INFO, PSTR("UFS: Type %d mounted with %d kB free"), ufs_type, UfsInfo(1, 0));
+ AddLog_P(LOG_LEVEL_INFO, PSTR("UFS: FlashFS mounted with %d kB free"), UfsInfo(1, 0));
}
}
-
#ifdef USE_SDCARD
void UfsCheckSDCardInit(void) {
-
-#ifdef ESP8266
- if (PinUsed(GPIO_SPI_CLK) && PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO)) {
-#endif // ESP8266
-
-#ifdef ESP32
if (TasmotaGlobal.spi_enabled) {
-#endif // ESP32
int8_t cs = SDCARD_CS_PIN;
if (PinUsed(GPIO_SDCARD_CS)) {
cs = Pin(GPIO_SDCARD_CS);
@@ -172,10 +167,10 @@ void UfsCheckSDCardInit(void) {
// make sd card the global filesystem
#ifdef ESP8266
// on esp8266 sdcard info takes several seconds !!!, so we ommit it here
- AddLog_P(LOG_LEVEL_INFO, PSTR("UFS: SDCARD mounted"));
+ AddLog_P(LOG_LEVEL_INFO, PSTR("UFS: SDCard mounted"));
#endif // ESP8266
#ifdef ESP32
- AddLog_P(LOG_LEVEL_INFO, PSTR("UFS: SDCARD mounted with %d kB free"), UfsInfo(1, 0));
+ AddLog_P(LOG_LEVEL_INFO, PSTR("UFS: SDCard mounted with %d kB free"), UfsInfo(1, 0));
#endif // ESP32
}
}
@@ -279,7 +274,7 @@ uint8_t UfsReject(char *name) {
\*********************************************************************************************/
bool TfsFileExists(const char *fname){
- if (!ufs_type) { return false; }
+ if (!ffs_type) { return false; }
bool yes = ffsp->exists(fname);
if (!yes) {
@@ -289,7 +284,7 @@ bool TfsFileExists(const char *fname){
}
bool TfsSaveFile(const char *fname, const uint8_t *buf, uint32_t len) {
- if (!ufs_type) { return false; }
+ if (!ffs_type) { return false; }
File file = ffsp->open(fname, "w");
if (!file) {
@@ -303,7 +298,7 @@ bool TfsSaveFile(const char *fname, const uint8_t *buf, uint32_t len) {
}
bool TfsInitFile(const char *fname, uint32_t len, uint8_t init_value) {
- if (!ufs_type) { return false; }
+ if (!ffs_type) { return false; }
File file = ffsp->open(fname, "w");
if (!file) {
@@ -319,7 +314,7 @@ bool TfsInitFile(const char *fname, uint32_t len, uint8_t init_value) {
}
bool TfsLoadFile(const char *fname, uint8_t *buf, uint32_t len) {
- if (!ufs_type) { return false; }
+ if (!ffs_type) { return false; }
if (!TfsFileExists(fname)) { return false; }
File file = ffsp->open(fname, "r");
@@ -334,7 +329,7 @@ bool TfsLoadFile(const char *fname, uint8_t *buf, uint32_t len) {
}
bool TfsDeleteFile(const char *fname) {
- if (!ufs_type) { return false; }
+ if (!ffs_type) { return false; }
if (!ffsp->remove(fname)) {
AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Delete failed"));
@@ -354,24 +349,48 @@ void (* const kUFSCommand[])(void) PROGMEM = {
&UFSInfo, &UFSType, &UFSSize, &UFSFree, &UFSDelete};
void UFSInfo(void) {
- Response_P(PSTR("{\"Ufs\":{\"Type\":%d,\"Size\":%d,\"Free\":%d}}"), ufs_type, UfsInfo(0, 0), UfsInfo(1, 0));
+ Response_P(PSTR("{\"Ufs\":{\"Type\":%d,\"Size\":%d,\"Free\":%d}"), ufs_type, UfsInfo(0, 0), UfsInfo(1, 0));
+ if (ffs_type && (ffs_type != ufs_type)) {
+ ResponseAppend_P(PSTR(",{\"Type\":%d,\"Size\":%d,\"Free\":%d}"), ffs_type, UfsInfo(0, 1), UfsInfo(1, 1));
+ }
+ ResponseJsonEnd();
}
void UFSType(void) {
- ResponseCmndNumber(ufs_type);
+ if (ffs_type && (ffs_type != ufs_type)) {
+ Response_P(PSTR("{\"%s\":[%d,%d]}"), XdrvMailbox.command, ufs_type, ffs_type);
+ } else {
+ ResponseCmndNumber(ufs_type);
+ }
}
void UFSSize(void) {
- ResponseCmndNumber(UfsInfo(0, 0));
+ if (ffs_type && (ffs_type != ufs_type)) {
+ Response_P(PSTR("{\"%s\":[%d,%d]}"), XdrvMailbox.command, UfsInfo(0, 0), UfsInfo(0, 1));
+ } else {
+ ResponseCmndNumber(UfsInfo(0, 0));
+ }
}
void UFSFree(void) {
- ResponseCmndNumber(UfsInfo(1, 0));
+ if (ffs_type && (ffs_type != ufs_type)) {
+ Response_P(PSTR("{\"%s\":[%d,%d]}"), XdrvMailbox.command, UfsInfo(1, 0), UfsInfo(1, 1));
+ } else {
+ ResponseCmndNumber(UfsInfo(1, 0));
+ }
}
void UFSDelete(void) {
+ // UfsDelete sdcard or flashfs file if only one of them available
+ // UfsDelete2 flashfs file if available
if (XdrvMailbox.data_len > 0) {
- if (!TfsDeleteFile(XdrvMailbox.data)) {
+ bool result = false;
+ if (ffs_type && (ffs_type != ufs_type) && (2 == XdrvMailbox.index)) {
+ result = TfsDeleteFile(XdrvMailbox.data);
+ } else {
+ result = (ufs_type && ufsp->remove(XdrvMailbox.data));
+ }
+ if (!result) {
ResponseCmndChar(D_JSON_FAILED);
} else {
ResponseCmndDone();
From f1d15c015c927decdeef687de92d8b54bfbe299d Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 15 Jan 2021 16:19:56 +0100
Subject: [PATCH 64/71] Fix ESP8266 SPI detection
---
tasmota/support_tasmota.ino | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index 3ac17a490..e4ae34177 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -1625,8 +1625,8 @@ void GpioInit(void)
if (!TasmotaGlobal.soft_spi_enabled) {
bool valid_cs = (ValidSpiPinUsed(GPIO_SPI_CS) ||
ValidSpiPinUsed(GPIO_RC522_CS) ||
- ValidSpiPinUsed(GPIO_NRF24_CS) ||
- ValidSpiPinUsed(GPIO_ILI9341_CS) ||
+ (ValidSpiPinUsed(GPIO_NRF24_CS) && ValidSpiPinUsed(GPIO_NRF24_DC)) ||
+ (ValidSpiPinUsed(GPIO_ILI9341_CS) && ValidSpiPinUsed(GPIO_ILI9341_DC)) ||
ValidSpiPinUsed(GPIO_EPAPER29_CS) ||
ValidSpiPinUsed(GPIO_EPAPER42_CS) ||
ValidSpiPinUsed(GPIO_ILI9488_CS) ||
@@ -1634,17 +1634,11 @@ void GpioInit(void)
ValidSpiPinUsed(GPIO_RA8876_CS) ||
ValidSpiPinUsed(GPIO_ST7789_DC) || // ST7789 CS may be omitted so chk DC too
ValidSpiPinUsed(GPIO_ST7789_CS) ||
- ValidSpiPinUsed(GPIO_SSD1331_CS) ||
+ (ValidSpiPinUsed(GPIO_SSD1331_CS) && ValidSpiPinUsed(GPIO_SSD1331_DC)) ||
ValidSpiPinUsed(GPIO_SDCARD_CS)
);
- bool valid_dc = (ValidSpiPinUsed(GPIO_SPI_DC) ||
- ValidSpiPinUsed(GPIO_NRF24_DC) ||
- ValidSpiPinUsed(GPIO_ILI9341_DC) ||
- ValidSpiPinUsed(GPIO_ST7789_DC) ||
- ValidSpiPinUsed(GPIO_SSD1331_DC)
- );
// If SPI_CS and/or SPI_DC is used they must be valid
- TasmotaGlobal.spi_enabled = (valid_cs && valid_dc) ? SPI_MOSI_MISO : SPI_NONE;
+ TasmotaGlobal.spi_enabled = (valid_cs) ? SPI_MOSI_MISO : SPI_NONE;
if (TasmotaGlobal.spi_enabled) {
TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO);
SetPin(12, AGPIO(GPIO_SPI_MISO));
From 86cd22e95f60d27a148ebe77108efdd6695cde58 Mon Sep 17 00:00:00 2001
From: Vic
Date: Fri, 15 Jan 2021 16:44:59 +0100
Subject: [PATCH 65/71] D_COUNT is used as a noun, not as a verb
---
tasmota/language/de_DE.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index 3ae7a842d..161f31482 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -73,7 +73,7 @@
#define D_COMMAND "Befehl"
#define D_CONNECTED "verbunden"
#define D_CORS_DOMAIN "CORS Domain"
-#define D_COUNT "zählen"
+#define D_COUNT "Anzahl" // used as a noun throughout
#define D_COUNTER "Zähler"
#define D_CT_POWER "CT Power"
#define D_CURRENT "Strom" // As in Voltage and Current
From cc43530639e7eab46a560dccea9e90aaae6a9123 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Fri, 15 Jan 2021 18:23:05 +0100
Subject: [PATCH 66/71] ESP32 support for TLS MQTT using BearSSL (same as
ESP8266)
---
CHANGELOG.md | 1 +
tasmota/StackThunk_light.cpp | 3 ++
tasmota/WiFiClientSecureLightBearSSL.cpp | 55 +++++++++++++++++++++---
tasmota/WiFiClientSecureLightBearSSL.h | 10 +++++
tasmota/xdrv_02_mqtt.ino | 5 +++
5 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e7e207f17..79e41be9e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Support for BS814A-2 8-button touch buttons by Peter Franck (#10447)
- Support for up to 4 I2C SEESAW_SOIL Capacitance & Temperature sensors by Peter Franck (#10481)
- ESP8266 Support for 2MB and up linker files with 1MB and up LittleFS
+- ESP32 support for TLS MQTT using BearSSL (same as ESP8266)
### Breaking Changed
- ESP32 switch from default SPIFFS to default LittleFS file system loosing current (zigbee) files
diff --git a/tasmota/StackThunk_light.cpp b/tasmota/StackThunk_light.cpp
index 8f8b9a23a..b85e19033 100644
--- a/tasmota/StackThunk_light.cpp
+++ b/tasmota/StackThunk_light.cpp
@@ -28,6 +28,7 @@
#include "my_user_config.h"
#include "tasmota_configurations.h"
+#if defined(ESP8266) && defined(USE_TLS)
#include
#include
#include "StackThunk_light.h"
@@ -145,3 +146,5 @@ void stack_thunk_light_fatal_overflow()
}
};
+
+#endif
\ No newline at end of file
diff --git a/tasmota/WiFiClientSecureLightBearSSL.cpp b/tasmota/WiFiClientSecureLightBearSSL.cpp
index f91d96cfc..6d7ed37b4 100755
--- a/tasmota/WiFiClientSecureLightBearSSL.cpp
+++ b/tasmota/WiFiClientSecureLightBearSSL.cpp
@@ -22,7 +22,7 @@
#include "my_user_config.h"
#include "tasmota_configurations.h"
-#if defined(ESP8266) && defined(USE_TLS)
+#if defined(USE_TLS)
// #define DEBUG_TLS
// #define DEBUG_ESP_SSL
@@ -47,7 +47,9 @@ extern "C" {
#include "lwip/tcp.h"
#include "lwip/inet.h"
#include "lwip/netif.h"
-#include
+#ifdef ESP8266
+ #include
+#endif
#include "c_types.h"
#include
@@ -57,11 +59,15 @@ extern "C" {
#include "coredecls.h"
#define LOG_HEAP_SIZE(a) _Log_heap_size(a)
void _Log_heap_size(const char *msg) {
+#ifdef ESP8266
register uint32_t *sp asm("a1");
int freestack = 4 * (sp - g_pcont->stack);
Serial.printf("%s %d, Fragmentation=%d, Thunkstack=%d, Free stack=%d, FreeContStack=%d\n",
msg, ESP.getFreeHeap(), ESP.getHeapFragmentation(), stack_thunk_light_get_max_usage(),
freestack, ESP.getFreeContStack());
+#elif defined(ESP32)
+ Serial.printf("> Heap %s = %d\n", msg, uxTaskGetStackHighWaterMark(nullptr));
+#endif
}
#else
#define LOG_HEAP_SIZE(a)
@@ -71,6 +77,7 @@ void _Log_heap_size(const char *msg) {
extern uint32_t UtcTime(void);
extern uint32_t CfgTime(void);
+#ifdef ESP8266 // Stack thunk is not needed with ESP32
// Stack thunked versions of calls
// Initially in BearSSLHelpers.h
extern "C" {
@@ -164,6 +171,8 @@ unsigned char *min_br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, si
#define br_ssl_engine_sendrec_ack min_br_ssl_engine_sendrec_ack
#define br_ssl_engine_sendrec_buf min_br_ssl_engine_sendrec_buf
+#endif // ESP8266
+
//#define DEBUG_ESP_SSL
#ifdef DEBUG_ESP_SSL
//#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__)
@@ -201,19 +210,23 @@ void WiFiClientSecure_light::_clear() {
// Constructor
WiFiClientSecure_light::WiFiClientSecure_light(int recv, int xmit) : WiFiClient() {
_clear();
-LOG_HEAP_SIZE("StackThunk before");
+ // LOG_HEAP_SIZE("StackThunk before");
//stack_thunk_light_add_ref();
-LOG_HEAP_SIZE("StackThunk after");
+ // LOG_HEAP_SIZE("StackThunk after");
// now finish the setup
setBufferSizes(recv, xmit); // reasonable minimum
allocateBuffers();
}
WiFiClientSecure_light::~WiFiClientSecure_light() {
+#ifdef ESP8266
if (_client) {
_client->unref();
_client = nullptr;
}
+#elif defined(ESP32)
+ stop();
+#endif
//_cipher_list = nullptr; // std::shared will free if last reference
_freeSSL();
}
@@ -258,6 +271,7 @@ void WiFiClientSecure_light::setBufferSizes(int recv, int xmit) {
_iobuf_out_size = xmit;
}
+#ifdef ESP8266
bool WiFiClientSecure_light::stop(unsigned int maxWaitMs) {
bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush()
_freeSSL();
@@ -268,6 +282,17 @@ bool WiFiClientSecure_light::flush(unsigned int maxWaitMs) {
(void) _run_until(BR_SSL_SENDAPP);
return WiFiClient::flush(maxWaitMs);
}
+#elif defined(ESP32)
+void WiFiClientSecure_light::stop(void) {
+ WiFiClient::stop(); // calls our virtual flush()
+ _freeSSL();
+}
+
+void WiFiClientSecure_light::flush(void) {
+ (void) _run_until(BR_SSL_SENDAPP);
+ WiFiClient::flush();
+}
+#endif
int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) {
DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port);
@@ -307,7 +332,11 @@ void WiFiClientSecure_light::_freeSSL() {
}
bool WiFiClientSecure_light::_clientConnected() {
+#ifdef ESP8266
return (_client && _client->state() == ESTABLISHED);
+#elif defined(ESP32)
+ return WiFiClient::connected();
+#endif
}
uint8_t WiFiClientSecure_light::connected() {
@@ -489,7 +518,7 @@ size_t WiFiClientSecure_light::peekBytes(uint8_t *buffer, size_t length) {
achieved, this function returns 0. On error, it returns -1.
*/
int WiFiClientSecure_light::_run_until(unsigned target, bool blocking) {
-//LOG_HEAP_SIZE("_run_until 1");
+ //LOG_HEAP_SIZE("_run_until 1");
if (!ctx_present()) {
DEBUG_BSSL("_run_until: Not connected\n");
return -1;
@@ -506,9 +535,15 @@ int WiFiClientSecure_light::_run_until(unsigned target, bool blocking) {
return -1;
}
+#ifdef ESP8266
if (!(_client->state() == ESTABLISHED) && !WiFiClient::available()) {
return (state & target) ? 0 : -1;
}
+#elif defined(ESP32)
+ if (!_clientConnected() && !WiFiClient::available()) {
+ return (state & target) ? 0 : -1;
+ }
+#endif
/*
If there is some record data to send, do it. This takes
@@ -898,12 +933,16 @@ bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
do { // used to exit on Out of Memory error and keep all cleanup code at the same place
// ============================================================
// allocate Thunk stack, move to alternate stack and initialize
+#ifdef ESP8266
stack_thunk_light_add_ref();
+#endif // ESP8266
LOG_HEAP_SIZE("Thunk allocated");
DEBUG_BSSL("_connectSSL: start connection\n");
_freeSSL();
clearLastError();
- if (!stack_thunk_light_get_stack_bot()) break;
+#ifdef ESP8266
+ if (!stack_thunk_light_get_stack_bot()) break;
+#endif // ESP8266
_ctx_present = true;
_eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
@@ -964,10 +1003,12 @@ bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
}
#endif
LOG_HEAP_SIZE("_connectSSL.end");
+#ifdef ESP8266
_max_thunkstack_use = stack_thunk_light_get_max_usage();
stack_thunk_light_del_ref();
//stack_thunk_light_repaint();
LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk");
+#endif // ESP8266
#ifdef USE_MQTT_TLS_CA_CERT
free(x509_minimal);
@@ -982,7 +1023,9 @@ bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
// if we arrived here, this means we had an OOM error, cleaning up
setLastError(ERR_OOM);
DEBUG_BSSL("_connectSSL: Out of memory\n");
+#ifdef ESP8266
stack_thunk_light_del_ref();
+#endif
#ifdef USE_MQTT_TLS_CA_CERT
free(x509_minimal);
#else
diff --git a/tasmota/WiFiClientSecureLightBearSSL.h b/tasmota/WiFiClientSecureLightBearSSL.h
index f480a9d42..f88a9f17f 100755
--- a/tasmota/WiFiClientSecureLightBearSSL.h
+++ b/tasmota/WiFiClientSecureLightBearSSL.h
@@ -43,7 +43,11 @@ class WiFiClientSecure_light : public WiFiClient {
uint8_t connected() override;
size_t write(const uint8_t *buf, size_t size) override;
+ #ifdef ESP8266
size_t write_P(PGM_P buf, size_t size) override;
+ #else
+ size_t write_P(PGM_P buf, size_t size);
+ #endif
size_t write(const char *buf) {
return write((const uint8_t*)buf, strlen(buf));
}
@@ -55,11 +59,17 @@ class WiFiClientSecure_light : public WiFiClient {
int available() override;
int read() override;
int peek() override;
+ #ifdef ESP8266
size_t peekBytes(uint8_t *buffer, size_t length) override;
bool flush(unsigned int maxWaitMs);
bool stop(unsigned int maxWaitMs);
void flush() override { (void)flush(0); }
void stop() override { (void)stop(0); }
+ #else
+ size_t peekBytes(uint8_t *buffer, size_t length);
+ void flush() override;
+ void stop() override;
+ #endif
// Only check SHA1 fingerprint of public key
void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2,
diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino
index 15e99f352..9a0acba75 100644
--- a/tasmota/xdrv_02_mqtt.ino
+++ b/tasmota/xdrv_02_mqtt.ino
@@ -679,8 +679,13 @@ void MqttReconnect(void) {
if (MqttClient.connect(TasmotaGlobal.mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, lwt_retain, TasmotaGlobal.mqtt_data, MQTT_CLEAN_SESSION)) {
#ifdef USE_MQTT_TLS
if (Mqtt.mqtt_tls) {
+#ifdef ESP8266
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connected in %d ms, max ThunkStack used %d"),
millis() - mqtt_connect_time, tlsClient->getMaxThunkStackUse());
+#elif defined(ESP32)
+ AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connected in %d ms, stack low mark %d"),
+ millis() - mqtt_connect_time, uxTaskGetStackHighWaterMark(nullptr));
+#endif
if (!tlsClient->getMFLNStatus()) {
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "MFLN not supported by TLS server"));
}
From 6d0005cc290975a0da56d2ccf11dd726bafc02d6 Mon Sep 17 00:00:00 2001
From: Vic
Date: Fri, 15 Jan 2021 19:02:09 +0100
Subject: [PATCH 67/71] some more improvements on german strings
---
tasmota/language/de_DE.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index 161f31482..071bfaaa0 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -143,8 +143,8 @@
#define D_POWERUSAGE_REACTIVE "Blindleistung"
#define D_PRESSURE "Luftdruck"
#define D_PRESSUREATSEALEVEL "Luftdruck auf Meereshöhe"
-#define D_PROGRAM_FLASH_SIZE "Ges. Flash Speicher"
-#define D_PROGRAM_SIZE "Ben. Flash Speicher"
+#define D_PROGRAM_FLASH_SIZE "Flash nutzbar"
+#define D_PROGRAM_SIZE "Größe Programm"
#define D_PROJECT "Projekt"
#define D_RAIN "Regen"
#define D_RANGE "Bereich"
@@ -333,7 +333,7 @@
#define D_PROGRAM_VERSION "Tasmota Version"
#define D_BUILD_DATE_AND_TIME "Build-Datum & -Uhrzeit"
#define D_CORE_AND_SDK_VERSION "Core-/SDK-Version"
-#define D_FLASH_WRITE_COUNT "Anz. Flash Schreibzugriffe"
+#define D_FLASH_WRITE_COUNT "Anz. Flash-Schreibzyklen"
#define D_MAC_ADDRESS "MAC-Adresse"
#define D_MQTT_HOST "MQTT Host"
#define D_MQTT_PORT "MQTT Port"
@@ -343,12 +343,12 @@
#define D_MQTT_GROUP_TOPIC "MQTT Group Topic"
#define D_MQTT_FULL_TOPIC "MQTT Full Topic"
#define D_MQTT_NO_RETAIN "MQTT No Retain"
-#define D_MDNS_DISCOVERY "mDNS-Ermittlung"
-#define D_MDNS_ADVERTISE "mDNS-Bekanntmachung"
+#define D_MDNS_DISCOVERY "mDNS-Erkennung"
+#define D_MDNS_ADVERTISE "mDNS-Freigaben"
#define D_ESP_CHIP_ID "ESP Chip ID"
#define D_FLASH_CHIP_ID "Flash Chip ID"
-#define D_FLASH_CHIP_SIZE "Realer Flash Speicher"
-#define D_FREE_PROGRAM_SPACE "Verf. Flash Speicher"
+#define D_FLASH_CHIP_SIZE "Größe Flash-Chip"
+#define D_FREE_PROGRAM_SPACE "Flash frei"
#define D_UPGRADE_BY_WEBSERVER "Update über Web-Server"
#define D_OTA_URL "OTA-URL"
From af798b40e20cee018dfa857670d3d46adbc180b6 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 15 Jan 2021 20:59:56 +0100
Subject: [PATCH 68/71] fix compile ESP8266
---
pio-tools/download_fs.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/pio-tools/download_fs.py b/pio-tools/download_fs.py
index f43bec128..4343adee3 100644
--- a/pio-tools/download_fs.py
+++ b/pio-tools/download_fs.py
@@ -24,8 +24,9 @@ platform = env.PioPlatform()
board = env.BoardConfig()
mcu = board.get("build.mcu", "esp32")
# Hack for using mklittlefs instead of mkspiffs -> needed since littlefs is not supported with this for ESP32
-#print("Replace MKSPIFFSTOOL with mklittlefs")
-env.Replace( MKSPIFFSTOOL=platform.get_package_dir("tool-mklittlefs") + '/mklittlefs' )
+if env["PIOPLATFORM"] == "espressif32":
+ #print("Replace MKSPIFFSTOOL with mklittlefs")
+ env.Replace( MKSPIFFSTOOL=platform.get_package_dir("tool-mklittlefs") + '/mklittlefs' )
# needed for later
AutodetectUploadPort(env)
From 9270e956d4c4297199e1cc93602155275da886b5 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sat, 16 Jan 2021 10:55:40 +0100
Subject: [PATCH 69/71] Zigbee increase timeout to 5s for first command
---
tasmota/xdrv_23_zigbee_7_0_statemachine.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/xdrv_23_zigbee_7_0_statemachine.ino b/tasmota/xdrv_23_zigbee_7_0_statemachine.ino
index 7c00cfb42..cc23c7a92 100644
--- a/tasmota/xdrv_23_zigbee_7_0_statemachine.ino
+++ b/tasmota/xdrv_23_zigbee_7_0_statemachine.ino
@@ -785,7 +785,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
ZI_WAIT_UNTIL(5000, ZBR_RSTACK) // wait for RSTACK message
// Init device and probe version
- ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV_FUNC(1000, ZBR_VERSION, &EZ_ReceiveCheckVersion) // check EXT PAN ID
+ ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV_FUNC(5000, ZBR_VERSION, &EZ_ReceiveCheckVersion) // check EXT PAN ID
// configure EFR32
ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord)
From 3bb15cda2a95731fabfd778ff2d13fcb60395d25 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 16 Jan 2021 11:18:40 +0100
Subject: [PATCH 70/71] Fix ESP32 MLX90640 compilation
---
tasmota/xdrv_43_mlx90640.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/xdrv_43_mlx90640.ino b/tasmota/xdrv_43_mlx90640.ino
index 18255c079..53cbcfe07 100644
--- a/tasmota/xdrv_43_mlx90640.ino
+++ b/tasmota/xdrv_43_mlx90640.ino
@@ -418,12 +418,12 @@ void MLX90640HandleWebGuiResponse(void){
if(_line==0){_buf[0]=1000+MLX90640.Ta;} //ambient temperature modulation hack
else{_buf[0]=(float)_line;}
memcpy((char*)&_buf[1],(char*)&MLX90640.To[_line*64],64*4);
- Webserver->send(200,PSTR("application/octet-stream"),(const char*)&_buf,65*4);
+ Webserver->send_P(200,PSTR("application/octet-stream"),(const char*)&_buf,65*4);
return;
}
WebGetArg("up", tmp, sizeof(tmp)); // update POI to browser
if (strlen(tmp)==1) {
- Webserver->send(200,PSTR("application/octet-stream"),(const char*)&MLX90640.pois,MLX90640_POI_NUM*2);
+ Webserver->send_P(200,PSTR("application/octet-stream"),(const char*)&MLX90640.pois,MLX90640_POI_NUM*2);
return;
}
else if (strlen(tmp)>2) { // receive updated POI from browser
From 7957e0c8998a3d5aa155a54765df9ef6fcf4b6c3 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sat, 16 Jan 2021 11:53:36 +0100
Subject: [PATCH 71/71] add tool-mklittlefs to tasmota32solo1
---
platformio_override_sample.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index e46754e7a..4db6a41b3 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -166,6 +166,7 @@ lib_extra_dirs =
[env:tasmota32solo1]
extends = env:tasmota32
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/raw/framework-arduinoespressif32/framework-arduinoespressif32-release_v3.3-solo1-4b325f52e.tar.gz
+ platformio/tool-mklittlefs @ ~1.203.200522
platformio/tool-esptoolpy @ ~1.30000.0
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${common32.build_flags}