From f15d583b06bfccc69e863e55ce682f655ecddc6b Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sun, 12 Apr 2020 21:59:57 +0200 Subject: [PATCH] [Cleanup] Code formatting for Pulse Counter --- src/_P003_Pulse.ino | 390 +++++++++++++++++++++-------------------- src/_Plugin_Helper.cpp | 22 ++- src/_Plugin_Helper.h | 23 ++- 3 files changed, 227 insertions(+), 208 deletions(-) diff --git a/src/_P003_Pulse.ino b/src/_P003_Pulse.ino index 478fc7f00..9b016eb7b 100644 --- a/src/_P003_Pulse.ino +++ b/src/_P003_Pulse.ino @@ -1,7 +1,8 @@ #ifdef USES_P003 -//####################################################################################################### -//#################################### Plugin 003: Pulse ############################################### -//####################################################################################################### + +// ####################################################################################################### +// #################################### Plugin 003: Pulse ############################################### +// ####################################################################################################### #include "_Plugin_Helper.h" @@ -19,7 +20,7 @@ void Plugin_003_pulse_interrupt3() ICACHE_RAM_ATTR; void Plugin_003_pulse_interrupt4() ICACHE_RAM_ATTR; void Plugin_003_pulsecheck(byte Index) ICACHE_RAM_ATTR; -//this takes 20 bytes of IRAM per handler +// this takes 20 bytes of IRAM per handler // void Plugin_003_pulse_interrupt5() ICACHE_RAM_ATTR; // void Plugin_003_pulse_interrupt6() ICACHE_RAM_ATTR; // void Plugin_003_pulse_interrupt7() ICACHE_RAM_ATTR; @@ -36,270 +37,277 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string) switch (function) { - case PLUGIN_DEVICE_ADD: - { - Device[++deviceCount].Number = PLUGIN_ID_003; - Device[deviceCount].Type = DEVICE_TYPE_SINGLE; - Device[deviceCount].VType = SENSOR_TYPE_SINGLE; - Device[deviceCount].Ports = 0; - Device[deviceCount].PullUpOption = false; - Device[deviceCount].InverseLogicOption = false; - Device[deviceCount].FormulaOption = true; - Device[deviceCount].ValueCount = 3; - Device[deviceCount].SendDataOption = true; - Device[deviceCount].TimerOption = true; - Device[deviceCount].GlobalSyncOption = true; - break; - } + { + Device[++deviceCount].Number = PLUGIN_ID_003; + Device[deviceCount].Type = DEVICE_TYPE_SINGLE; + Device[deviceCount].VType = SENSOR_TYPE_SINGLE; + Device[deviceCount].Ports = 0; + Device[deviceCount].PullUpOption = false; + Device[deviceCount].InverseLogicOption = false; + Device[deviceCount].FormulaOption = true; + Device[deviceCount].ValueCount = 3; + Device[deviceCount].SendDataOption = true; + Device[deviceCount].TimerOption = true; + Device[deviceCount].GlobalSyncOption = true; + break; + } case PLUGIN_GET_DEVICENAME: - { - string = F(PLUGIN_NAME_003); - break; - } + { + string = F(PLUGIN_NAME_003); + break; + } case PLUGIN_GET_DEVICEVALUENAMES: - { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_003)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_003)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_003)); - break; - } + { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_003)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_003)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_003)); + break; + } case PLUGIN_GET_DEVICEGPIONAMES: - { - event->String1 = formatGpioName_input(F("Pulse")); - break; - } + { + event->String1 = formatGpioName_input(F("Pulse")); + break; + } case PLUGIN_WEBFORM_LOAD: - { - addFormNumericBox(F("Debounce Time (mSec)"), F("p003") - , Settings.TaskDevicePluginConfig[event->TaskIndex][0]); + { + addFormNumericBox(F("Debounce Time (mSec)"), F("p003") + , Settings.TaskDevicePluginConfig[event->TaskIndex][0]); - byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][1]; - byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][2]; - String options[4] = { F("Delta"), F("Delta/Total/Time"), F("Total"), F("Delta/Total") }; - addFormSelector(F("Counter Type"), F("p003_countertype"), 4, options, NULL, choice ); + byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][1]; + byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][2]; + String options[4] = { F("Delta"), F("Delta/Total/Time"), F("Total"), F("Delta/Total") }; + addFormSelector(F("Counter Type"), F("p003_countertype"), 4, options, NULL, choice); - if (choice !=0) - addHtml(F("Total count is not persistent!")); - - String modeRaise[4]; - modeRaise[0] = F("LOW"); - modeRaise[1] = F("CHANGE"); - modeRaise[2] = F("RISING"); - modeRaise[3] = F("FALLING"); - int modeValues[4]; - modeValues[0] = LOW; - modeValues[1] = CHANGE; - modeValues[2] = RISING; - modeValues[3] = FALLING; - - addFormSelector(F("Mode Type"), F("p003_raisetype"), 4, modeRaise, modeValues, choice2 ); - - success = true; - break; + if (choice != 0) { + addHtml(F("Total count is not persistent!")); } + String modeRaise[4]; + modeRaise[0] = F("LOW"); + modeRaise[1] = F("CHANGE"); + modeRaise[2] = F("RISING"); + modeRaise[3] = F("FALLING"); + int modeValues[4]; + modeValues[0] = LOW; + modeValues[1] = CHANGE; + modeValues[2] = RISING; + modeValues[3] = FALLING; + + addFormSelector(F("Mode Type"), F("p003_raisetype"), 4, modeRaise, modeValues, choice2); + + success = true; + break; + } + case PLUGIN_WEBFORM_SAVE: - { - Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("p003")); - Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("p003_countertype")); - Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("p003_raisetype")); - success = true; - break; - } + { + Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("p003")); + Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("p003_countertype")); + Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("p003_raisetype")); + success = true; + break; + } case PLUGIN_WEBFORM_SHOW_VALUES: - { - addHtml(F("
")); - addHtml(String(ExtraTaskSettings.TaskDeviceValueNames[0])); - addHtml(F(":
")); - addHtml(String(Plugin_003_pulseCounter[event->TaskIndex])); - addHtml(F("
")); - addHtml(String(ExtraTaskSettings.TaskDeviceValueNames[1])); - addHtml(F(":
")); - addHtml(String(Plugin_003_pulseTotalCounter[event->TaskIndex])); - addHtml(F("
")); - addHtml(String(ExtraTaskSettings.TaskDeviceValueNames[2])); - addHtml(F(":
")); - addHtml(String(Plugin_003_pulseTime[event->TaskIndex])); - addHtml(F("
")); - success = true; - break; - } + { + addHtml(F("
")); + addHtml(String(ExtraTaskSettings.TaskDeviceValueNames[0])); + addHtml(F(":
")); + addHtml(String(Plugin_003_pulseCounter[event->TaskIndex])); + addHtml(F("
")); + addHtml(String(ExtraTaskSettings.TaskDeviceValueNames[1])); + addHtml(F(":
")); + addHtml(String(Plugin_003_pulseTotalCounter[event->TaskIndex])); + addHtml(F("
")); + addHtml(String(ExtraTaskSettings.TaskDeviceValueNames[2])); + addHtml(F(":
")); + addHtml(String(Plugin_003_pulseTime[event->TaskIndex])); + addHtml(F("
")); + success = true; + break; + } case PLUGIN_INIT: - { - - // Restore any value that may have been read from the RTC. - Plugin_003_pulseCounter[event->TaskIndex] = UserVar[event->BaseVarIndex]; - Plugin_003_pulseTotalCounter[event->TaskIndex] = UserVar[event->BaseVarIndex+1]; - Plugin_003_pulseTime[event->TaskIndex] = UserVar[event->BaseVarIndex+2]; + { + // Restore any value that may have been read from the RTC. + Plugin_003_pulseCounter[event->TaskIndex] = UserVar[event->BaseVarIndex]; + Plugin_003_pulseTotalCounter[event->TaskIndex] = UserVar[event->BaseVarIndex + 1]; + Plugin_003_pulseTime[event->TaskIndex] = UserVar[event->BaseVarIndex + 2]; - String log = F("INIT : Pulse "); - log += Settings.TaskDevicePin1[event->TaskIndex]; - addLog(LOG_LEVEL_INFO,log); - pinMode(Settings.TaskDevicePin1[event->TaskIndex], INPUT_PULLUP); - success = Plugin_003_pulseinit(Settings.TaskDevicePin1[event->TaskIndex], event->TaskIndex,Settings.TaskDevicePluginConfig[event->TaskIndex][2]); + String log = F("INIT : Pulse "); + log += Settings.TaskDevicePin1[event->TaskIndex]; + addLog(LOG_LEVEL_INFO, log); + pinMode(Settings.TaskDevicePin1[event->TaskIndex], INPUT_PULLUP); + success = + Plugin_003_pulseinit(Settings.TaskDevicePin1[event->TaskIndex], event->TaskIndex, + Settings.TaskDevicePluginConfig[event->TaskIndex][2]); - break; - } + break; + } case PLUGIN_READ: - { - UserVar[event->BaseVarIndex] = Plugin_003_pulseCounter[event->TaskIndex]; - UserVar[event->BaseVarIndex+1] = Plugin_003_pulseTotalCounter[event->TaskIndex]; - UserVar[event->BaseVarIndex+2] = Plugin_003_pulseTime[event->TaskIndex]; + { + UserVar[event->BaseVarIndex] = Plugin_003_pulseCounter[event->TaskIndex]; + UserVar[event->BaseVarIndex + 1] = Plugin_003_pulseTotalCounter[event->TaskIndex]; + UserVar[event->BaseVarIndex + 2] = Plugin_003_pulseTime[event->TaskIndex]; - switch (Settings.TaskDevicePluginConfig[event->TaskIndex][1]) + switch (Settings.TaskDevicePluginConfig[event->TaskIndex][1]) + { + case 0: { - case 0: - { - event->sensorType = SENSOR_TYPE_SINGLE; - UserVar[event->BaseVarIndex] = Plugin_003_pulseCounter[event->TaskIndex]; - break; - } - case 1: - { - event->sensorType = SENSOR_TYPE_TRIPLE; - UserVar[event->BaseVarIndex] = Plugin_003_pulseCounter[event->TaskIndex]; - UserVar[event->BaseVarIndex+1] = Plugin_003_pulseTotalCounter[event->TaskIndex]; - UserVar[event->BaseVarIndex+2] = Plugin_003_pulseTime[event->TaskIndex]; - break; - } - case 2: - { - event->sensorType = SENSOR_TYPE_SINGLE; - UserVar[event->BaseVarIndex] = Plugin_003_pulseTotalCounter[event->TaskIndex]; - break; - } - case 3: - { - event->sensorType = SENSOR_TYPE_DUAL; - UserVar[event->BaseVarIndex] = Plugin_003_pulseCounter[event->TaskIndex]; - UserVar[event->BaseVarIndex+1] = Plugin_003_pulseTotalCounter[event->TaskIndex]; - break; - } + event->sensorType = SENSOR_TYPE_SINGLE; + UserVar[event->BaseVarIndex] = Plugin_003_pulseCounter[event->TaskIndex]; + break; } - Plugin_003_pulseCounter[event->TaskIndex] = 0; - success = true; - break; - } - - case PLUGIN_WRITE: - { - String command = parseString(string, 1); - - if (command == F("resetpulsecounter")) + case 1: { - // Valid commands: - // - resetpulsecounter - // - resetpulsecounter,taskindex + event->sensorType = SENSOR_TYPE_TRIPLE; + UserVar[event->BaseVarIndex] = Plugin_003_pulseCounter[event->TaskIndex]; + UserVar[event->BaseVarIndex + 1] = Plugin_003_pulseTotalCounter[event->TaskIndex]; + UserVar[event->BaseVarIndex + 2] = Plugin_003_pulseTime[event->TaskIndex]; + break; + } + case 2: + { + event->sensorType = SENSOR_TYPE_SINGLE; + UserVar[event->BaseVarIndex] = Plugin_003_pulseTotalCounter[event->TaskIndex]; + break; + } + case 3: + { + event->sensorType = SENSOR_TYPE_DUAL; + UserVar[event->BaseVarIndex] = Plugin_003_pulseCounter[event->TaskIndex]; + UserVar[event->BaseVarIndex + 1] = Plugin_003_pulseTotalCounter[event->TaskIndex]; + break; + } + } + Plugin_003_pulseCounter[event->TaskIndex] = 0; + success = true; + break; + } - // Allow for an optional taskIndex parameter. When not given it will take the first task with this plugin. - if (!pluginOptionalTaskIndexArgumentMatch(event->TaskIndex, string, 1)) { - break; - } + case PLUGIN_WRITE: + { + String command = parseString(string, 1); + + if (command == F("resetpulsecounter")) + { + // Valid commands: + // - resetpulsecounter + // - resetpulsecounter,taskindex + + // Allow for an optional taskIndex parameter. When not given it will take the first task with this plugin. + if (!pluginOptionalTaskIndexArgumentMatch(event->TaskIndex, string, 1)) { + break; + } Plugin_003_pulseCounter[event->TaskIndex] = 0; - Plugin_003_pulseTotalCounter[event->TaskIndex] = 0; + Plugin_003_pulseTotalCounter[event->TaskIndex] = 0; Plugin_003_pulseTime[event->TaskIndex] = 0; - - success = true; // Command is handled. - } - if (command == F("setpulsecountertotal")) - { - // Valid commands: - // - setpulsecountertotal,value - // - setpulsecountertotal,value,taskindex - - // First check if (optional) task index matches. - if (!pluginOptionalTaskIndexArgumentMatch(event->TaskIndex, string, 2)) { - break; - } - - int par1; - - if (validIntFromString(parseString(string, 2), par1)) - { - Plugin_003_pulseTotalCounter[event->TaskIndex] = par1; - success = true; // Command is handled. - } - } - break; + success = true; // Command is handled. } + + if (command == F("setpulsecountertotal")) + { + // Valid commands: + // - setpulsecountertotal,value + // - setpulsecountertotal,value,taskindex + + // First check if (optional) task index matches. + if (!pluginOptionalTaskIndexArgumentMatch(event->TaskIndex, string, 2)) { + break; + } + + int par1; + + if (validIntFromString(parseString(string, 2), par1)) + { + Plugin_003_pulseTotalCounter[event->TaskIndex] = par1; + success = true; // Command is handled. + } + } + break; + } } return success; } /*********************************************************************************************\ - * Check Pulse Counters (called from irq handler) +* Check Pulse Counters (called from irq handler) \*********************************************************************************************/ void Plugin_003_pulsecheck(byte Index) { noInterrupts(); // s0170071: avoid nested interrups due to bouncing. - - // s0170071: the following gives a glitch if millis() rolls over (every 50 days) and there is a bouncing to be avoided at the exact same time. Very rare. - // Alternatively there is timePassedSince(Plugin_003_pulseTimePrevious[Index]); but this is not in IRAM at this time, so do not use in a ISR! - const unsigned long PulseTime=millis() - Plugin_003_pulseTimePrevious[Index]; - - if(PulseTime > (unsigned long)Settings.TaskDevicePluginConfig[Index][0]) // check with debounce time for this task - { - Plugin_003_pulseCounter[Index]++; - Plugin_003_pulseTotalCounter[Index]++; - Plugin_003_pulseTime[Index] = PulseTime; - Plugin_003_pulseTimePrevious[Index]=millis(); - } - interrupts(); // enable interrupts again. + + // s0170071: the following gives a glitch if millis() rolls over (every 50 days) and there is a bouncing to be avoided at the exact same + // time. Very rare. + // Alternatively there is timePassedSince(Plugin_003_pulseTimePrevious[Index]); but this is not in IRAM at this time, so do not use in a + // ISR! + const unsigned long PulseTime = millis() - Plugin_003_pulseTimePrevious[Index]; + + if (PulseTime > (unsigned long)Settings.TaskDevicePluginConfig[Index][0]) // check with debounce time for this task + { + Plugin_003_pulseCounter[Index]++; + Plugin_003_pulseTotalCounter[Index]++; + Plugin_003_pulseTime[Index] = PulseTime; + Plugin_003_pulseTimePrevious[Index] = millis(); + } + interrupts(); // enable interrupts again. } - /*********************************************************************************************\ - * Pulse Counter IRQ handlers +* Pulse Counter IRQ handlers \*********************************************************************************************/ void Plugin_003_pulse_interrupt1() { Plugin_003_pulsecheck(0); } + void Plugin_003_pulse_interrupt2() { Plugin_003_pulsecheck(1); } + void Plugin_003_pulse_interrupt3() { Plugin_003_pulsecheck(2); } + void Plugin_003_pulse_interrupt4() { Plugin_003_pulsecheck(3); } + void Plugin_003_pulse_interrupt5() { Plugin_003_pulsecheck(4); } + void Plugin_003_pulse_interrupt6() { Plugin_003_pulsecheck(5); } + void Plugin_003_pulse_interrupt7() { Plugin_003_pulsecheck(6); } + void Plugin_003_pulse_interrupt8() { Plugin_003_pulsecheck(7); } - /*********************************************************************************************\ - * Init Pulse Counters +* Init Pulse Counters \*********************************************************************************************/ bool Plugin_003_pulseinit(byte Par1, byte Index, byte Mode) { - switch (Index) { case 0: @@ -314,6 +322,7 @@ bool Plugin_003_pulseinit(byte Par1, byte Index, byte Mode) case 3: attachInterrupt(Par1, Plugin_003_pulse_interrupt4, Mode); break; + // case 4: // attachInterrupt(Par1, Plugin_003_pulse_interrupt5, Mode); // break; @@ -327,10 +336,11 @@ bool Plugin_003_pulseinit(byte Par1, byte Index, byte Mode) // attachInterrupt(Par1, Plugin_003_pulse_interrupt8, Mode); // break; default: - addLog(LOG_LEVEL_ERROR,F("PULSE: Error, only the first 4 tasks can be pulse counters.")); - return(false); + addLog(LOG_LEVEL_ERROR, F("PULSE: Error, only the first 4 tasks can be pulse counters.")); + return false; } - return(true); + return true; } + #endif // USES_P003 diff --git a/src/_Plugin_Helper.cpp b/src/_Plugin_Helper.cpp index eedfea1e9..5b93c7d04 100644 --- a/src/_Plugin_Helper.cpp +++ b/src/_Plugin_Helper.cpp @@ -21,7 +21,6 @@ String PCONFIG_LABEL(int n) { return F("error"); } - void resetPluginTaskData() { for (taskIndex_t i = 0; i < TASKS_MAX; ++i) { Plugin_task_data[i] = nullptr; @@ -39,17 +38,18 @@ void clearPluginTaskData(taskIndex_t taskIndex) { void initPluginTaskData(taskIndex_t taskIndex, PluginTaskData_base *data) { if (!validTaskIndex(taskIndex)) { return; } - + clearPluginTaskData(taskIndex); + if (Settings.TaskDeviceEnabled[taskIndex]) { - Plugin_task_data[taskIndex] = data; + Plugin_task_data[taskIndex] = data; Plugin_task_data[taskIndex]->_taskdata_pluginID = Settings.TaskDeviceNumber[taskIndex]; } } PluginTaskData_base* getPluginTaskData(taskIndex_t taskIndex) { if (pluginTaskData_initialized(taskIndex)) { - return Plugin_task_data[taskIndex]; + return Plugin_task_data[taskIndex]; } return nullptr; } @@ -58,12 +58,13 @@ bool pluginTaskData_initialized(taskIndex_t taskIndex) { if (!validTaskIndex(taskIndex)) { return false; } - return Plugin_task_data[taskIndex] != nullptr && - (Plugin_task_data[taskIndex]->_taskdata_pluginID == Settings.TaskDeviceNumber[taskIndex]); + return Plugin_task_data[taskIndex] != nullptr && + (Plugin_task_data[taskIndex]->_taskdata_pluginID == Settings.TaskDeviceNumber[taskIndex]); } String getPluginCustomArgName(int varNr) { String argName = F("pc_arg"); + argName += varNr + 1; return argName; } @@ -75,12 +76,14 @@ String getPluginCustomArgName(int varNr) { // Note that the varNr of the custom values should not conflict with the existing variable numbers (e.g. start at VARS_PER_TASK) String pluginWebformShowValue(taskIndex_t taskIndex, byte varNr, const String& label, const String& value, bool addTrailingBreak) { String result; - size_t length = 96 + label.length() + value.length(); + size_t length = 96 + label.length() + value.length(); String breakStr = F("
"); + if (addTrailingBreak) { length += breakStr.length(); } result.reserve(length); + if (varNr > 0) { result += breakStr; } @@ -97,21 +100,22 @@ String pluginWebformShowValue(taskIndex_t taskIndex, byte varNr, const String& l result += "'>"; result += value; result += ""; + if (addTrailingBreak) { result += breakStr; } return result; } - bool pluginOptionalTaskIndexArgumentMatch(taskIndex_t taskIndex, byte paramNr, const String& string) { if (!validTaskIndex(taskIndex)) { return false; } const taskIndex_t found_taskIndex = parseCommandArgumentTaskIndex(string, paramNr); + if (!validTaskIndex(found_taskIndex)) { // Optional parameter not present return true; } - return (found_taskIndex == taskIndex); + return found_taskIndex == taskIndex; } diff --git a/src/_Plugin_Helper.h b/src/_Plugin_Helper.h index 4f5db652c..2c20e37de 100644 --- a/src/_Plugin_Helper.h +++ b/src/_Plugin_Helper.h @@ -63,33 +63,38 @@ struct PluginTaskData_base { }; +void resetPluginTaskData(); -void resetPluginTaskData(); +void clearPluginTaskData(taskIndex_t taskIndex); -void clearPluginTaskData(taskIndex_t taskIndex); - -void initPluginTaskData(taskIndex_t taskIndex, PluginTaskData_base *data); +void initPluginTaskData(taskIndex_t taskIndex, + PluginTaskData_base *data); PluginTaskData_base* getPluginTaskData(taskIndex_t taskIndex); -bool pluginTaskData_initialized(taskIndex_t taskIndex); +bool pluginTaskData_initialized(taskIndex_t taskIndex); -String getPluginCustomArgName(int varNr); +String getPluginCustomArgName(int varNr); // Helper function to create formatted custom values for display in the devices overview page. // When called from PLUGIN_WEBFORM_SHOW_VALUES, the last item should add a traling div_br class // if the regular values should also be displayed. // The call to PLUGIN_WEBFORM_SHOW_VALUES should only return success = true when no regular values should be displayed // Note that the varNr of the custom values should not conflict with the existing variable numbers (e.g. start at VARS_PER_TASK) -String pluginWebformShowValue(taskIndex_t taskIndex, byte varNr, const String& label, const String& value, bool addTrailingBreak = false); +String pluginWebformShowValue(taskIndex_t taskIndex, + byte varNr, + const String& label, + const String& value, + bool addTrailingBreak = false); // Check if given parameter nr matches with given taskIndex. // paramNr == 0 -> command, paramNr == 1 -> 1st parameter // When there is no parameter at given parameter position, this function will return true. (as it is an optional parameter) // When given taskIndex is invalid, return value is false. // Return if parameter at given paramNr matches given taskIndex. -bool pluginOptionalTaskIndexArgumentMatch(taskIndex_t taskIndex, byte paramNr, const String& string); - +bool pluginOptionalTaskIndexArgumentMatch(taskIndex_t taskIndex, + byte paramNr, + const String& string); #endif // PLUGIN_HELPER_H