Skip to content

Commit d259f96

Browse files
authored
Merge pull request #5193 from tonhuisman/feature/Commands-add-looptimersetandrun
[Commands] Add commands LoopTimerSetAndRun (_ms)
2 parents e450177 + 31b4447 commit d259f96

File tree

9 files changed

+64
-12
lines changed

9 files changed

+64
-12
lines changed

docs/source/Plugin/P000_commands.repl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,15 @@
357357

358358
N.B. the timernr is shared between ``TimerSet`` and ``LoopTimerSet``"
359359
"
360+
LoopTimerSetAndRun
361+
362+
LoopTimerSetAndRun_ms","
363+
Set a Loop-Timer using ``LoopTimerSet`` or ``LoopTimerSet_ms`` and immediately run the first iteration.
364+
365+
If a ``<nr of loops>`` value > 0 is included in the command, that count is decremented by 1 for the first iteration, as expected.
366+
367+
Useful for setting a keep-alive timer, and also send the initial keep-alive signal immediately."
368+
"
360369
meminfo","
361370
:red:`Internal`","
362371
Will send summary of struct sizes to the serial port.

docs/source/Rules/Rules.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,6 +1746,11 @@ Added on 2020/08/12:
17461746
* ``loopTimerSet`` To create a repeating timer with constant interval (seconds).
17471747
* ``loopTimerSet_ms`` Same as ``loopTimerSet``, with msec interval.
17481748

1749+
Added on 2024/12/23:
1750+
1751+
* ``loopTimerSetAndRun`` Same as ``loopTimerSet``, and immediately starts the 1st iteration.
1752+
* ``loopTimerSetAndRun_ms`` Same as ``loopTimerSetAndRun``, with msec interval.
1753+
17491754
Here a small example to show how to start/stop and pause loop timers.
17501755
This can be used to create quite complex timing schemas, especially when
17511756
using multiple timers which are set to a relative prime interval.

src/src/Commands/InternalCommands.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,13 +319,15 @@ bool InternalCommands::executeInternalCommand()
319319
#ifndef BUILD_NO_DIAGNOSTIC_COMMANDS
320320
case ESPEasy_cmd_e::jsonportstatus: COMMAND_CASE_A(Command_JSONPortStatus, -1); // Diagnostic.h
321321
#endif // ifndef BUILD_NO_DIAGNOSTIC_COMMANDS
322-
case ESPEasy_cmd_e::let: COMMAND_CASE_A(Command_Rules_Let, 2); // Rules.h
323-
case ESPEasy_cmd_e::load: COMMAND_CASE_A(Command_Settings_Load, 0); // Settings.h
324-
case ESPEasy_cmd_e::logentry: COMMAND_CASE_A(Command_logentry, -1); // Diagnostic.h
325-
case ESPEasy_cmd_e::looptimerset: COMMAND_CASE_A(Command_Loop_Timer_Set, 3); // Timers.h
326-
case ESPEasy_cmd_e::looptimerset_ms: COMMAND_CASE_A(Command_Loop_Timer_Set_ms, 3); // Timers.h
327-
case ESPEasy_cmd_e::longpulse: COMMAND_CASE_A(Command_GPIO_LongPulse, 5); // GPIO.h
328-
case ESPEasy_cmd_e::longpulse_ms: COMMAND_CASE_A(Command_GPIO_LongPulse_Ms, 5); // GPIO.h
322+
case ESPEasy_cmd_e::let: COMMAND_CASE_A(Command_Rules_Let, 2); // Rules.h
323+
case ESPEasy_cmd_e::load: COMMAND_CASE_A(Command_Settings_Load, 0); // Settings.h
324+
case ESPEasy_cmd_e::logentry: COMMAND_CASE_A(Command_logentry, -1); // Diagnostic.h
325+
case ESPEasy_cmd_e::looptimerset: COMMAND_CASE_A(Command_Loop_Timer_Set, 3); // Timers.h
326+
case ESPEasy_cmd_e::looptimerset_ms: COMMAND_CASE_A(Command_Loop_Timer_Set_ms, 3); // Timers.h
327+
case ESPEasy_cmd_e::looptimersetandrun: COMMAND_CASE_A(Command_Loop_Timer_SetAndRun, 3); // Timers.h
328+
case ESPEasy_cmd_e::looptimersetandrun_ms: COMMAND_CASE_A(Command_Loop_Timer_SetAndRun_ms, 3); // Timers.h
329+
case ESPEasy_cmd_e::longpulse: COMMAND_CASE_A(Command_GPIO_LongPulse, 5); // GPIO.h
330+
case ESPEasy_cmd_e::longpulse_ms: COMMAND_CASE_A(Command_GPIO_LongPulse_Ms, 5); // GPIO.h
329331
#ifndef BUILD_NO_DIAGNOSTIC_COMMANDS
330332
case ESPEasy_cmd_e::logportstatus: COMMAND_CASE_A(Command_logPortStatus, 0); // Diagnostic.h
331333
case ESPEasy_cmd_e::lowmem: COMMAND_CASE_A(Command_Lowmem, 0); // Diagnostic.h

src/src/Commands/InternalCommands_decoder.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ const char Internal_commands_l[] PROGMEM =
103103
"logentry|"
104104
"looptimerset|"
105105
"looptimerset_ms|"
106+
"looptimersetandrun|"
107+
"looptimersetandrun_ms|"
106108
"longpulse|"
107109
"longpulse_ms|"
108110
#ifndef BUILD_NO_DIAGNOSTIC_COMMANDS

src/src/Commands/InternalCommands_decoder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ enum class ESPEasy_cmd_e : uint8_t {
8181
logentry,
8282
looptimerset,
8383
looptimerset_ms,
84+
looptimersetandrun,
85+
looptimersetandrun_ms,
8486
longpulse,
8587
longpulse_ms,
8688
#ifndef BUILD_NO_DIAGNOSTIC_COMMANDS

src/src/Commands/Timer.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
#include "../Helpers/Misc.h"
1818
#include "../Helpers/Scheduler.h"
1919

20-
const __FlashStringHelper * command_setRulesTimer(int msecFromNow, int timerIndex, int recurringCount) {
20+
const __FlashStringHelper * command_setRulesTimer(int msecFromNow, int timerIndex, int recurringCount, bool startImmediately = false) {
2121
if (msecFromNow < 0)
2222
{
2323
addLog(LOG_LEVEL_ERROR, F("TIMER: time must be positive"));
2424
} else {
2525
// start new timer when msecFromNow > 0
2626
// Clear timer when msecFromNow == 0
27-
if (Scheduler.setRulesTimer(msecFromNow, timerIndex, recurringCount))
27+
if (Scheduler.setRulesTimer(msecFromNow, timerIndex, recurringCount, startImmediately))
2828
{
2929
return return_command_success_flashstr();
3030
}
@@ -78,6 +78,34 @@ const __FlashStringHelper * Command_Loop_Timer_Set_ms (struct EventStruct *event
7878
);
7979
}
8080

81+
const __FlashStringHelper * Command_Loop_Timer_SetAndRun (struct EventStruct *event, const char* Line)
82+
{
83+
int recurringCount = event->Par3;
84+
if (recurringCount == 0) {
85+
// if the optional 3rd parameter is not given, set it to "run always"
86+
recurringCount = -1;
87+
}
88+
return command_setRulesTimer(
89+
event->Par2 * 1000, // msec from now
90+
event->Par1, // timer index
91+
recurringCount,
92+
true);
93+
}
94+
95+
const __FlashStringHelper * Command_Loop_Timer_SetAndRun_ms (struct EventStruct *event, const char* Line)
96+
{
97+
int recurringCount = event->Par3;
98+
if (recurringCount == 0) {
99+
// if the optional 3rd parameter is not given, set it to "run always"
100+
recurringCount = -1;
101+
}
102+
return command_setRulesTimer(
103+
event->Par2, // interval
104+
event->Par1, // timer index
105+
recurringCount,
106+
true);
107+
}
108+
81109
const __FlashStringHelper * Command_Timer_Pause(struct EventStruct *event, const char *Line)
82110
{
83111
if (Scheduler.pause_rules_timer(event->Par1)) {

src/src/Commands/Timer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const __FlashStringHelper * Command_Timer_Set (struct EventStruct *event, const
77
const __FlashStringHelper * Command_Timer_Set_ms (struct EventStruct *event, const char* Line);
88
const __FlashStringHelper * Command_Loop_Timer_Set (struct EventStruct *event, const char* Line);
99
const __FlashStringHelper * Command_Loop_Timer_Set_ms (struct EventStruct *event, const char* Line);
10+
const __FlashStringHelper * Command_Loop_Timer_SetAndRun (struct EventStruct *event, const char* Line);
11+
const __FlashStringHelper * Command_Loop_Timer_SetAndRun_ms (struct EventStruct *event, const char* Line);
1012
const __FlashStringHelper * Command_Timer_Pause (struct EventStruct *event, const char* Line);
1113
const __FlashStringHelper * Command_Timer_Resume (struct EventStruct *event, const char* Line);
1214
const __FlashStringHelper * Command_Delay (struct EventStruct *event, const char* Line);

src/src/Helpers/Scheduler.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,11 @@ void setPluginTaskTimer(unsigned long msecFromNow,
161161
// @param msecFromNow Number of milli seconds from now (also used as interval for recurring)
162162
// @param timerIndex The index of the timer used. (1 ... max)
163163
// @param recurringCount Number of times needed to run (-1 for always)
164+
// @param startImmediately Run immediately
164165
bool setRulesTimer(unsigned long msecFromNow,
165166
unsigned int timerIndex,
166-
int recurringCount = 0);
167+
int recurringCount = 0,
168+
bool startImmediately = false);
167169

168170
void process_rules_timer(SchedulerTimerID timerID,
169171
unsigned long lasttimer);

src/src/Helpers/Scheduler_RulesTimer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ static bool checkRulesTimerIndex(unsigned int timerIndex) {
2525
return true;
2626
}
2727

28-
bool ESPEasy_Scheduler::setRulesTimer(unsigned long msecFromNow, unsigned int timerIndex, int recurringCount) {
28+
bool ESPEasy_Scheduler::setRulesTimer(unsigned long msecFromNow, unsigned int timerIndex, int recurringCount, bool startImmediately) {
2929
if (!checkRulesTimerIndex(timerIndex)) { return false; }
3030

3131
const RulesTimerID timerID(timerIndex);
3232

3333
const systemTimerStruct timer_data(recurringCount, msecFromNow, timerIndex);
3434

3535
systemTimers[timerID.mixed_id] = timer_data;
36-
setNewTimerAt(timerID, millis() + msecFromNow);
36+
setNewTimerAt(timerID, millis() + (startImmediately ? 10 : msecFromNow));
3737
return true;
3838
}
3939

0 commit comments

Comments
 (0)