Greenhouse delay

Hey,
I'm relatively new to arduino, but I've decided to delve into building an automated greenhouse. The basic design is to have two motors controlled via syren 10, along with a rtc and some inductive sensors to pul a tarp along a frame I'm building, and blackout the greenhouse. Classic Light Deprivation. The one issue I've run into, funny enough, happens to be a delay. I'll post the code to make it clear.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
#include <Sabertooth.h>

Sabertooth ST1[2] = { Sabertooth(128), Sabertooth(129) } ;
LiquidCrystal_I2C lcd(0x27,20,4) ;
DS3231  rtc(SDA, SCL) ;

Time  t ;

int Hor ;
int Min ;
int Sec ;

boolean relay_on = false ;

int induct = A0 ;
//int inductB = A1 ;
int Relay = 8 ;
int val = 0 ;

//....................................
void setup() 
{ Serial.begin(9600) ;
  Wire.begin() ;
  rtc.begin() ;
  SabertoothTXPinSerial.begin(9600) ;
  Sabertooth::autobaud(SabertoothTXPinSerial) ;
  lcd.init() ;
  lcd.begin(20,4) ;
  lcd.backlight() ;
  delay(3000) ;
  pinMode(Relay,OUTPUT) ;
  digitalWrite(Relay,HIGH) ;
  lcd.setCursor(0,0) ;
  lcd.print("Flowers") ;
  delay(2000) ;
  lcd.clear() ; }
  
//....................................  
void loop() 
{ val = analogRead(induct) ;
  
  t = rtc.getTime() ;
  Hor = t.hour ;
  Min = t.min ;
  Sec = t.sec ;

  lcd.setCursor(0,0) ;
  lcd.print("Time: ") ;
  lcd.print(rtc.getTimeStr()) ;
  lcd.setCursor(0,1) ;
  lcd.print("Date: ") ;
  lcd.print(rtc.getDateStr()) ;
  delay(1000) ;
  lcd.clear() ;
  
//.................................... 
if( Hor == 12 &&  (Min == 36 || Min == 37))

{ OpenFunc() ; }

//....................................
if(Hor == 19 && (Min == 30 || Min == 31))

{ CloseFunc() ; }}

//....................................
 void OpenFunc ()
{{digitalWrite(Relay,LOW) ;
  relay_on = true ;}//without a delay here the inductive sensor on A0 can be monitored and the timing //for turning off the motors and relay is on point. Obviously the delay can cause some issues, like the //reading never being registered, and the motor continues to pull on something it shouldn't 

if (relay_on)
 {lcd.setCursor(0,3) ;
  lcd.print("Opening...") ;
  ST1[0].motor(1, 60) ;
  ST1[1].motor(1, 60) ;
  
if (val <= 500 or Hor == 12 && Min == 38)
 {ST1[0].motor(1, 0) ;
  ST1[1].motor(1, 0) ;
  delay(3000) ;
  digitalWrite(Relay,HIGH) ;
  relay_on = false ;
  delay(60000);
  lcd.clear() ;
  lcd.setCursor(8,3) ;
  lcd.print("Open") ;
  delay(2000) ; }}}

//....................................
void CloseFunc ()
{{digitalWrite(Relay,LOW) ;
  delay(4000);                // this delay I'm trying to replace with a millis() timer or something 
  relay_on = true ;}        //needs to be at least two seconds so the desktop power supply  
                                   //has time to power the motor controller

if (relay_on)
  {lcd.setCursor(0,3) ;
  lcd.print("Closing...") ;
  ST1[0].motor(1, -60) ;
  ST1[1].motor(1, -60) ;
  
if (val <=500 or Hor == 19 && Min == 33)
{ ST1[0].motor(1, 0) ;
  ST1[1].motor(1, 0) ;
  delay(3000) ;
  digitalWrite(Relay,HIGH) ;
  relay_on = false ;
  delay(60000);
  lcd.clear() ;
  lcd.setCursor(7,3) ;
  lcd.print("Closed.") ;
  delay(2000) ; }}}

To put it simply, I'd like to make a millis timer similar to

unsigned long futuresight = 0 ;
unsigned long interval= 0;
void setup(){
  Serial.begin(9600);
  }
void loop(){
  unsigned long currentMillis = millis();
 if( (currentMillis - futuresight <= interval)){
    futuresight = currentMillis + 10000UL;
  Serial.print("worked");
}}

that happens to be predictive, called upon initiation of the relay, only activates the if statement the once and is not horribly complicated. If I can't figure a means out now no delay is no big deal until I do

You should NOT be adding times. Addition is not guaranteed to work. Subtraction is, unless the interval between the times is greater than the rollover interval (49+ days).

Your code structure makes for difficult reading. NOTHING should follow the { on the same line, in a function definition statement or if statement.

You have useless curly braces that do not help.

You call OpenFunc() when hour is 12 and minute is 38 or 39, but, in the function, ignore the minute=39 possibility. Why?

Do you KNOW the precedence of operators? Which is higher - <=, ==, ||, or &&?

If you do not KNOW, use parentheses, so that what you want and what the compiler does are the same thing.

You can't just replace delay() with millis() in a function, if you don't call the function over and over.

You really need to keep track of whether what you are trying to open or close is open, opening, closed, or closing. Take the desired action only if the current state is appropriate. That is, do not try to open a door that is opening. Do not try to close a door that is closed.

Hoping that spinning the motors for a fixed amount of time will result in complete opening or closing is a bad idea. Limit switches are a good idea.

The analog int is an inductive sensor which is triggered by a piece of metal on the track, so thats my limit switch, considering the amount of time to close the tarp is less than two minutes easily. In fact the sensor was the initial reason I was looking to replace the delay, seeing as it disrupts reading and can stop the if statement from ever occurring. As for the futuresight, its was just a test I made off of:

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 5000;  


void setup()
{
  Serial.begin(9600);
  
  Serial.println("begin");

  startMillis = millis();  //save the start time
}

void loop()
{ currentMillis = millis();
  if (currentMillis - startMillis >= period) 
  { startMillis = currentMillis;
    Serial.print("there's the bacon");}}

to get a better idea of how I might capture millis once using an unsigned long and compare it to a running and repeating millis call like currentMillis. So I'm on board with subtraction, I was more curious on how I might condition the statement so I can get a reading once when the opening or closing operation starts that I can reliably call on and subtract from the elapsed millis in an if statement. Curious of any suggestions.
As for the brackets, I was just happy the code worked, but I'll be sure to try and look up how to make that look better, and add states that define when the tarp is open closed opening closing etc. as to not potentially try to open an open tarp, seems like a good safety.
As for the precedence of operators, I don't quite know what you're referring to but I'll see what I can dig up
Thanks

also probably worth mentioning the relay turns on the DC power supply for the sabertooths

Ya know I think I may have finally figured it out. Think I'll share in case someone else is trying to do the same. the DS3231 library is from rinkydink.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
#include <Sabertooth.h>

Sabertooth ST1[2] = { Sabertooth(128), Sabertooth(129) } ;
LiquidCrystal_I2C lcd(0x27,20,4) ;
DS3231  rtc(SDA, SCL) ;

Time  t ;

unsigned long currentMillis;
unsigned long interval = 5000UL;
unsigned long startfun;
unsigned long startMillis;

boolean closed_state = 0 ;
boolean open_state = 1 ;
boolean opening_state = 0 ;
boolean closing_state = 0 ;

int Hor ;
int Min ;
int Sec ;

boolean relay_on = false ;
boolean relay_off = true ;

int induct = A0 ;
//int inductB = A1 ;
int Relay = 8 ;
int val = 0 ;

//....................................
void setup() 
{ Serial.begin(9600) ;
  Wire.begin() ;
  rtc.begin() ;
  SabertoothTXPinSerial.begin(9600) ;
  Sabertooth::autobaud(SabertoothTXPinSerial) ;
  lcd.init() ;
  lcd.begin(20,4) ;
  lcd.backlight() ;
  pinMode(Relay,OUTPUT) ;
  digitalWrite(Relay,HIGH) ;
  startMillis = millis();
  lcd.setCursor(0,0) ;
  lcd.print("Flowers") ;
  delay(2000) ;
  lcd.clear() ; }
  
//....................................  
void loop() 
{ val = analogRead(induct) ;
  currentMillis = millis() ;
  
  t = rtc.getTime() ;
  Hor = t.hour ;
  Min = t.min ;
  Sec = t.sec ;
  if ((currentMillis - startMillis) >= 1000UL){
  lcd.setCursor(0,0) ;
  lcd.print("Time: ") ;
  lcd.print(rtc.getTimeStr()) ;
  lcd.setCursor(0,1) ;
  lcd.print("Date: ") ;
  lcd.print(rtc.getDateStr()) ;
  startMillis = currentMillis ;}
    
//.................................... 
if( Hor == 7 &&  (Min == 30 || Min == 31))

{ OpenFunc () ; }

//....................................
if(Hor == 19 && (Min == 30 || Min == 31))

{ CloseFunc () ; }}

//....................................
void OpenFunc(){
  if (relay_off and closed_state){
      digitalWrite(Relay,LOW) ;
      startfun = currentMillis;
      relay_on = true ;
      relay_off = false;
} else {
  if((currentMillis - startfun)>= interval){
      if (relay_on){
          lcd.setCursor(0,3) ;
          lcd.print("Opening...") ;
          closed_state = false ;
          opening_state = true ;
          ST1[0].motor(1, 60) ;
          ST1[1].motor(1, 60) ;
  
          if (val <= 500 or (Hor == 7 && Min == 31 && Sec == 55)){
              ST1[0].motor(1, 0) ;
              ST1[1].motor(1, 0) ;
              delay(3500) ;
              opening_state = false ;
              open_state = true ;
              digitalWrite(Relay,HIGH) ;
              relay_off = true ;
              lcd.clear() ;
              lcd.setCursor(8,3) ;
              lcd.print("Open") ; 
              relay_on = false ;
           }
         }
       }
     }
   }

//....................................
void CloseFunc(){
  if (relay_off and open_state){
      digitalWrite(Relay,LOW) ;
      startfun = currentMillis ;
      relay_on = true ;
      relay_off = false;
} else {
  if((currentMillis - startfun)>= interval){
      if (relay_on){
          lcd.setCursor(0,3) ;
          lcd.print("Closing...") ;
          open_state = false ;
          closing_state = true ;
          ST1[0].motor(1, -60) ;
          ST1[1].motor(1, -60) ;
 
          if (val <=500 or (Hor == 19 && Min == 31 && Sec == 55)){
              ST1[0].motor(1, 0) ;
              ST1[1].motor(1, 0) ;
              delay(3500) ;
              closing_state = false ;
              closed_state = true ;
              digitalWrite(Relay,HIGH) ;
              relay_off = true ;
              lcd.clear() ;
              lcd.setCursor(7,3) ;
              lcd.print("Closed.") ;
              relay_on = false ;
            }
          }
        }
      }
    }

thanks for your suggestions Paul