mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
[Commands] Add flag to be a bit more tolerant in last argument parsing
A lot of people were running into issues with some commands no longer working after the changes of strict rules parsing. This flag in the advanced settings may help out a bit. Also the logs are made a bit more elaborate to describe the issue.
This commit is contained in:
+35
-8
@@ -42,15 +42,31 @@ bool checkNrArguments(const char *cmd, const char *Line, int nrArguments) {
|
||||
log += Line;
|
||||
} else {
|
||||
// Check for one more argument than allowed, since we apparently have one.
|
||||
for (int i = 0; i <= nrArguments; ++i) {
|
||||
if (i < nrArguments) {
|
||||
log += F(" arg");
|
||||
bool done = false;
|
||||
int i = 1;
|
||||
while (!done) {
|
||||
String parameter;
|
||||
if (i == nrArguments) {
|
||||
parameter = tolerantParseStringKeepCase(Line, i+ 1);
|
||||
done = true;
|
||||
} else {
|
||||
log += F(" extraArg");
|
||||
parameter = parseStringKeepCase(Line, i + 1);
|
||||
}
|
||||
log += String(i + 1);
|
||||
log += '=';
|
||||
log += parseString(Line, i + 2);
|
||||
done = parameter.length() == 0;
|
||||
if (!done) {
|
||||
if (i <= nrArguments) {
|
||||
if (Settings.TolerantLastArgParse() && i == nrArguments) {
|
||||
log += F(" (fixed)");
|
||||
}
|
||||
log += F(" Arg");
|
||||
} else {
|
||||
log += F(" ExtraArg");
|
||||
}
|
||||
log += String(i);
|
||||
log += '=';
|
||||
log += parameter;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
log += F(" lineLength=");
|
||||
@@ -60,6 +76,17 @@ bool checkNrArguments(const char *cmd, const char *Line, int nrArguments) {
|
||||
log += Line;
|
||||
log += '_';
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
|
||||
if (!Settings.TolerantLastArgParse()) {
|
||||
log = F("Command not executed!");
|
||||
} else {
|
||||
log = F("Command executed, but may fail.");
|
||||
}
|
||||
log += F(" See: https://github.com/letscontrolit/ESPEasy/issues/2724");
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
if (Settings.TolerantLastArgParse()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -138,7 +165,7 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch
|
||||
case 'l': {
|
||||
COMMAND_CASE( "let", Command_Rules_Let, 2); // Rules.h
|
||||
COMMAND_CASE( "load", Command_Settings_Load, 0); // Settings.h
|
||||
COMMAND_CASE( "logentry", Command_logentry, 2); // Diagnostic.h
|
||||
COMMAND_CASE( "logentry", Command_logentry, 1); // Diagnostic.h
|
||||
COMMAND_CASE("logportstatus", Command_logPortStatus, 0); // Diagnostic.h
|
||||
COMMAND_CASE( "lowmem", Command_Lowmem, 0); // Diagnostic.h
|
||||
break;
|
||||
|
||||
+3
-1
@@ -60,7 +60,9 @@
|
||||
#define DEFAULT_WIFI_NONE_SLEEP false // When set, the wifi will be set to no longer sleep (more power
|
||||
// used and need reboot to reset mode)
|
||||
#define DEFAULT_GRATUITOUS_ARP false // When set, the node will send periodical gratuitous ARP
|
||||
// packets to announce itself.
|
||||
// packets to announce itself.
|
||||
#define DEFAULT_TOLERANT_LAST_ARG_PARSE false // When set, the last argument of some commands will be parsed to the end of the line
|
||||
// See: https://github.com/letscontrolit/ESPEasy/issues/2724
|
||||
|
||||
// --- Default Controller ------------------------------------------------------------------------------
|
||||
#define DEFAULT_CONTROLLER false // true or false enabled or disabled, set 1st controller
|
||||
|
||||
@@ -158,6 +158,7 @@ String parseString(const String& string, byte indexFind);
|
||||
String parseStringKeepCase(const String& string, byte indexFind);
|
||||
String parseStringToEnd(const String& string, byte indexFind);
|
||||
String parseStringToEndKeepCase(const String& string, byte indexFind);
|
||||
String tolerantParseStringKeepCase(const String& string, byte indexFind);
|
||||
|
||||
int parseCommandArgumentInt(const String& string, unsigned int argc);
|
||||
|
||||
|
||||
@@ -476,6 +476,8 @@ bool remoteConfig(struct EventStruct *event, const String& string)
|
||||
if (parseString(string, 2) == F("task"))
|
||||
{
|
||||
String configTaskName = parseStringKeepCase(string, 3);
|
||||
// FIXME TD-er: This command is not using the tolerance setting
|
||||
// tolerantParseStringKeepCase(Line, 4);
|
||||
String configCommand = parseStringToEndKeepCase(string, 4);
|
||||
|
||||
if ((configTaskName.length() == 0) || (configCommand.length() == 0)) {
|
||||
|
||||
@@ -436,6 +436,14 @@ String parseStringToEndKeepCase(const String& string, byte indexFind) {
|
||||
return stripQuotes(result);
|
||||
}
|
||||
|
||||
String tolerantParseStringKeepCase(const String& string, byte indexFind)
|
||||
{
|
||||
if (Settings.TolerantLastArgParse()) {
|
||||
return parseStringToEndKeepCase(string, indexFind);
|
||||
}
|
||||
return parseStringKeepCase(string, indexFind);
|
||||
}
|
||||
|
||||
// escapes special characters in strings for use in html-forms
|
||||
void htmlEscape(String& html)
|
||||
{
|
||||
|
||||
@@ -65,6 +65,7 @@ void handle_advanced() {
|
||||
Settings.Latitude = getFormItemFloat(F("latitude"));
|
||||
Settings.Longitude = getFormItemFloat(F("longitude"));
|
||||
Settings.OldRulesEngine(isFormItemChecked(F("oldrulesengine")));
|
||||
Settings.TolerantLastArgParse(isFormItemChecked(F("tolerantargparse")));
|
||||
Settings.ForceWiFi_bg_mode(isFormItemChecked(getInternalLabel(LabelType::FORCE_WIFI_BG)));
|
||||
Settings.WiFiRestart_connection_lost(isFormItemChecked(getInternalLabel(LabelType::RESTART_WIFI_LOST_CONN)));
|
||||
Settings.EcoPowerMode(isFormItemChecked(getInternalLabel(LabelType::CPU_ECO_MODE)));
|
||||
@@ -89,6 +90,8 @@ void handle_advanced() {
|
||||
|
||||
addFormCheckBox(F("Rules"), F("userules"), Settings.UseRules);
|
||||
addFormCheckBox(F("Old Engine"), F("oldrulesengine"), Settings.OldRulesEngine());
|
||||
addFormCheckBox(F("Tolerant last parameter"), F("tolerantargparse"), Settings.TolerantLastArgParse());
|
||||
addFormNote(F("Perform less strict parsing on last argument of some commands (e.g. publish and sendToHttp)"));
|
||||
|
||||
addFormSubHeader(F("Controller Settings"));
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ String Command_Debug(struct EventStruct *event, const char *Line)
|
||||
String Command_logentry(struct EventStruct *event, const char *Line)
|
||||
{
|
||||
// FIXME TD-er: Add an extra optional parameter to set log level.
|
||||
addLog(LOG_LEVEL_INFO, parseStringKeepCase(Line, 2));
|
||||
addLog(LOG_LEVEL_INFO, tolerantParseStringKeepCase(Line, 2));
|
||||
return return_command_success();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
String Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
if (WiFiConnected()) {
|
||||
String strLine = Line;
|
||||
String host = parseString(strLine, 2);
|
||||
const int port = parseCommandArgumentInt(strLine, 2);
|
||||
String host = parseString(Line, 2);
|
||||
const int port = parseCommandArgumentInt(Line, 2);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("SendToHTTP: Host: ");
|
||||
log += host;
|
||||
@@ -24,7 +23,9 @@ String Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line)
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
if (!port < 0 || port > 65535) return return_command_failed();
|
||||
String path = parseStringToEndKeepCase(strLine, 4);
|
||||
// FIXME TD-er: This is not using the tolerant settings option.
|
||||
// String path = tolerantParseStringKeepCase(Line, 4);
|
||||
String path = parseStringToEndKeepCase(Line, 4);
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("SendToHTTP: Path: ");
|
||||
|
||||
@@ -52,7 +52,7 @@ String Command_MQTT_Publish(struct EventStruct *event, const char *Line)
|
||||
if (enabledMqttController >= 0) {
|
||||
// Command structure: Publish,<topic>,<value>
|
||||
String topic = parseStringKeepCase(Line, 2);
|
||||
String value = parseStringKeepCase(Line, 3);
|
||||
String value = tolerantParseStringKeepCase(Line, 3);
|
||||
addLog(LOG_LEVEL_DEBUG, String(F("Publish: ")) + topic + value);
|
||||
|
||||
if ((topic.length() > 0) && (value.length() > 0)) {
|
||||
|
||||
@@ -31,7 +31,7 @@ String Command_UPD_SendTo(struct EventStruct *event, const char *Line)
|
||||
int destUnit = parseCommandArgumentInt(Line, 1);
|
||||
if ((destUnit > 0) && (destUnit < 255))
|
||||
{
|
||||
String eventName = parseStringKeepCase(Line, 3);
|
||||
String eventName = tolerantParseStringKeepCase(Line, 3);
|
||||
SendUDPCommand(destUnit, eventName.c_str(), eventName.length());
|
||||
}
|
||||
return return_command_success();
|
||||
@@ -40,12 +40,13 @@ String Command_UPD_SendTo(struct EventStruct *event, const char *Line)
|
||||
String Command_UDP_SendToUPD(struct EventStruct *event, const char *Line)
|
||||
{
|
||||
if (WiFiConnected()) {
|
||||
String strLine = Line;
|
||||
String ip = parseString(strLine, 2);
|
||||
int port = parseCommandArgumentInt(strLine, 2);
|
||||
String ip = parseString(Line, 2);
|
||||
int port = parseCommandArgumentInt(Line, 2);
|
||||
|
||||
if (port < 0 || port > 65535) return return_command_failed();
|
||||
String message = parseStringToEndKeepCase(strLine, 4);
|
||||
// FIXME TD-er: This command is not using the tolerance setting
|
||||
// tolerantParseStringKeepCase(Line, 4);
|
||||
String message = parseStringToEndKeepCase(Line, 4);
|
||||
IPAddress UDP_IP;
|
||||
|
||||
if (UDP_IP.fromString(ip)) {
|
||||
|
||||
@@ -84,6 +84,10 @@
|
||||
#ifndef DEFAULT_GRATUITOUS_ARP
|
||||
#define DEFAULT_GRATUITOUS_ARP false // When set, the node will send periodical gratuitous ARP packets to announce itself.
|
||||
#endif
|
||||
#ifndef DEFAULT_TOLERANT_LAST_ARG_PARSE
|
||||
#define DEFAULT_TOLERANT_LAST_ARG_PARSE false // When set, the last argument of some commands will be parsed to the end of the line
|
||||
// See: https://github.com/letscontrolit/ESPEasy/issues/2724
|
||||
#endif
|
||||
|
||||
// --- Default Controller ------------------------------------------------------------------------------
|
||||
#ifndef DEFAULT_CONTROLLER
|
||||
|
||||
@@ -91,6 +91,16 @@ void SettingsStruct_tmpl<N_TASKS>::gratuitousARP(bool value) {
|
||||
setBitToUL(VariousBits1, 8, !value);
|
||||
}
|
||||
|
||||
template<unsigned int N_TASKS>
|
||||
bool SettingsStruct_tmpl<N_TASKS>::TolerantLastArgParse() {
|
||||
return getBitFromUL(VariousBits1, 9);
|
||||
}
|
||||
|
||||
template<unsigned int N_TASKS>
|
||||
void SettingsStruct_tmpl<N_TASKS>::TolerantLastArgParse(bool value) {
|
||||
setBitToUL(VariousBits1, 9, value);
|
||||
}
|
||||
|
||||
template<unsigned int N_TASKS>
|
||||
void SettingsStruct_tmpl<N_TASKS>::validate() {
|
||||
if (UDPPort > 65535) { UDPPort = 0; }
|
||||
@@ -213,6 +223,7 @@ void SettingsStruct_tmpl<N_TASKS>::clearMisc() {
|
||||
EcoPowerMode(DEFAULT_ECO_MODE);
|
||||
WifiNoneSleep(DEFAULT_WIFI_NONE_SLEEP);
|
||||
gratuitousARP(DEFAULT_GRATUITOUS_ARP);
|
||||
TolerantLastArgParse(DEFAULT_TOLERANT_LAST_ARG_PARSE);
|
||||
}
|
||||
|
||||
template<unsigned int N_TASKS>
|
||||
|
||||
@@ -42,6 +42,11 @@ class SettingsStruct_tmpl
|
||||
bool gratuitousARP();
|
||||
void gratuitousARP(bool value);
|
||||
|
||||
// Be a bit more tolerant when parsing the last argument of a command.
|
||||
// See: https://github.com/letscontrolit/ESPEasy/issues/2724
|
||||
bool TolerantLastArgParse();
|
||||
void TolerantLastArgParse(bool value);
|
||||
|
||||
void validate();
|
||||
|
||||
bool networkSettingsEmpty() const;
|
||||
|
||||
Reference in New Issue
Block a user