diff --git a/src/relay_chn_tilt.c b/src/relay_chn_tilt.c index acb6c47..9162258 100644 --- a/src/relay_chn_tilt.c +++ b/src/relay_chn_tilt.c @@ -104,6 +104,37 @@ static void relay_chn_tilt_start_timer_or_stop(relay_chn_tilt_ctl_t *tilt_ctl, e } } +/** + * @brief Checks if the relay channel can perform the current tilt command. + * + * This function evaluates whether a tilt command can be executed based on the + * channel's history. The rules are as follows: + * - Tilting in the same direction as the last full run command (e.g., TILT_FORWARD + * after a FORWARD run) is always allowed. + * - Tilting in the opposite direction of the last full run (e.g., TILT_REVERSE + * after a FORWARD run) is only allowed if the tilt counter is greater than zero, + * which indicates that the channel has previously tilted in the primary direction. + * - If the channel has not been run before, tilting is not allowed. + * + * @param tilt_ctl Pointer to the tilt control structure for the channel. + * @param tilt_cmd The tilt command to check against. + * + * @return true if the tilt command is allowed, false otherwise. + */ +static bool relay_chn_can_perform_tilt_cmd(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t tilt_cmd) +{ + relay_chn_cmd_t last_run_cmd = relay_chn_run_info_get_last_run_cmd(tilt_ctl->chn_ctl->run_info); + if (last_run_cmd == RELAY_CHN_CMD_FORWARD) { + return (tilt_cmd == RELAY_CHN_TILT_CMD_FORWARD) || + (tilt_cmd == RELAY_CHN_TILT_CMD_REVERSE && tilt_ctl->tilt_count > 0); + } else if (last_run_cmd == RELAY_CHN_CMD_REVERSE) { + return (tilt_cmd == RELAY_CHN_TILT_CMD_REVERSE) || + (tilt_cmd == RELAY_CHN_TILT_CMD_FORWARD && tilt_ctl->tilt_count > 0); + } + + return false; +} + // Issue a tilt command to a specific relay channel. static void relay_chn_tilt_issue_cmd(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t cmd) { @@ -128,6 +159,11 @@ static void relay_chn_tilt_issue_cmd(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_t return; } + if (!relay_chn_can_perform_tilt_cmd(tilt_ctl, cmd)) { + ESP_LOGD(TAG, "Cannot perform tilt command: %d for #%d", cmd, tilt_ctl->chn_ctl->id); + return; + } + // Set the command that will be processed tilt_ctl->cmd = cmd; switch (tilt_ctl->chn_ctl->state) {