#include <RTClib.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <avr/wdt.h>
//#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include "DHT.h"
#define DHTTYPE DHT22   // DHT 22  (AM2302)

SoftwareSerial gprs(10, 11);
RTC_DS1307 RTC;

// constants
#define pump1_led 2
#define pump2_led 3
#define blower_led 4
#define uvlight_led 5
#define FULLSTOP_led 6
#define override_led 13
#define go_led 12

#define pump1_button 51
#define pump2_button 48
#define blower_button 24
#define uvlight_button 25
#define FULLSTOP_button 26
#define override_button 27
#define go_button 28


#define pump1_relay 30
#define pump2_relay 31
#define blower_relay 32
#define uvlight_relay 33
#define biofilterPump_relay 34

#define sump_low 36
#define sump_high 37
#define biofilter_low 38
#define biofilter_high 39
#define flowPin 40
#define biofilterLevel 41
#define sumpLevel 42
#define A1_Low_Level 43
#define A1_High_Level 44
#define POWER 45
#define growoutSump 47
#define DHTPIN 46
#define dometemp 23
#define ONE_WIRE_BUS 22 // Data bus pin for temperature sensor reading


//LiquidCrystal lcd(52, 51, 50, 49, 48, 47);

const float pi = 3.142;
const float radius = 92;
float volume_sump;
float volume_tank;
float height;

int buttonState;
    int lastButtonState=LOW;
    long lastDebounceTime;
    long debounceDelay =50;


const long interval = 1000;
long previousmillis = 0;
long previousmillis2 = 0;
long previousmillis_ping = 0;
long ping_interval = 1000;
long short_interval = 200;
long interval_5s = 5000;
long interval_10s = 10000;
long interval_30s = 30000;
long interval_60s = 60000;
long blower_interval = 600000;
long override_timeout = 60000;
long flowTimer = 0;
long time = 0;
long interval_20min = 1200000;
long interval_30min = 1800000;
unsigned long ok_timer;
unsigned long lastok_timer;

unsigned long CURRENT_sump;
unsigned long PREVIOUS_sump;
unsigned long CURRENT_biofilter;
unsigned long PREVIOUS_biofilter;
unsigned long CURRENT_A1_Low;
unsigned long PREVIOUS_A1_Low;
unsigned long CURRENT_A1_High;
unsigned long PREVIOUS_A1_High;
unsigned long CURRENT_power;
unsigned long PREVIOUS_power;
unsigned long CURRENT_growoutSump;
unsigned long PREVIOUS_growoutSump;

unsigned long blowerOntime = 0;
unsigned long blowerOfftime = 0;
long blowerOninterval = 3000000;
long blowerOffinterval = 600000;

byte error = 0;
byte errorState = 0;
byte PREVIOUSerrorState = 0;
byte location;
byte activepump = 1;
byte last_activepump = 1;

byte sumpError = 0;
byte biofilterError = 0;
byte A1_Low_Error = 0;
byte A1_High_Error = 0;
byte POWERError = 0;
byte growoutSumpError = 0;

byte PREVsumpError = 0;
byte PREVbiofilterError = 0;
byte PREVA1_Low_error = 0;
byte PREVA1_High_error = 0;
byte PREVPOWERError = 0;
byte PREVgrowoutSumpError = 0;
byte PREVPOWERstateError = 0;

byte errorWarning = 0;
byte sumpWarning = 0;
byte bioWarning = 0;
byte A1_LowWarning = 0;
byte A1_HighWarning = 0;

byte pump1_state = 0;
byte pump2_state = 0;
byte blower_state = 1;
byte uvlight_state = 0;
byte biofilterPump_state = 0;

byte override_state = 0;
byte FULLSTOP_state = 1;
byte go_state = 0;
byte depthstatusSump = 0;
byte depthstatusBiofilter = 0;

byte flowState = 0;
char biofilterPump;
char pump1;
char pump2;
char blower;
char uvlight;
char sumpHigh[] = "SUMP LEVEL HIGH";
char inchar; //Will hold the incoming character from the Serial Port.

char mess1[] = "ALL SYSTEMS NOMINAL";
char mess2[] = "SYSTEM ERROR";
char mess3[] = "SUMP LEVEL HIGH";
char mess4[] = "A1 LEVEL HIGH";
char mess5[] = "A2 LEVEL LOW";
char mess6[] = "BIOFILTER HIGH";

int value, value2, value3, value4, value5, value6, value7 ;

int displace = 200;

//buttons

byte go_buttonState = 0;         // current state of the button
byte go_lastButtonState = 0;     // previous state of the button

byte FULLSTOP_buttonState = 0;         // current state of the button
byte FULLSTOP_lastButtonState = 0;     // previous state of the button

byte override_buttonState = 0;         // current state of the button
byte override_lastButtonState = 0;     // previous state of the button

byte pump1_buttonState = 0;         // current state of the button
byte pump1_lastButtonState = 0;     // previous state of the button

byte pump2_buttonState = 0;         // current state of the button
byte pump2_lastButtonState = 0;     // previous state of the button

byte blower_buttonState = 0;         // current state of the button
byte blower_lastButtonState = 0;     // previous state of the button

byte uvlight_buttonState = 0;         // current state of the button
byte uvlight_lastButtonState = 0;     // previous state of the button

float ambientH = 0;
float ambientT = 0;
float domeH = 0;
float domeT = 0;

DHT dht(DHTPIN, DHTTYPE);
DHT domeDHT(dometemp, DHTTYPE);
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

void setup() {
  //POWER_UP();
  wdt_enable(WDTO_8S);
  Wire.begin();
  dht.begin();
  RTC.begin();
  if (! RTC.isrunning())
  {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  sensors.begin();

  pinMode(FULLSTOP_button, INPUT_PULLUP);
  pinMode(override_button, INPUT_PULLUP);
  pinMode(go_button, INPUT_PULLUP);
  pinMode(pump1_button, INPUT_PULLUP);
  pinMode(pump2_button, INPUT_PULLUP);
  pinMode(blower_button, INPUT_PULLUP);
  pinMode(uvlight_button, INPUT_PULLUP);
  pinMode(sump_low, INPUT_PULLUP);
  pinMode(sump_high, INPUT_PULLUP);
  pinMode(flowPin, INPUT_PULLUP);

  pinMode(pump1_led, OUTPUT);
  pinMode(pump2_led, OUTPUT);
  pinMode(blower_led, OUTPUT);
  pinMode(uvlight_led, OUTPUT);
  pinMode(override_led, OUTPUT);
  pinMode(FULLSTOP_led, OUTPUT);

  pinMode(pump1_relay, OUTPUT);
  pinMode(pump2_relay, OUTPUT);
  pinMode(blower_relay, OUTPUT);
  pinMode(uvlight_relay, OUTPUT);
  pinMode(biofilterPump_relay, OUTPUT);

  pinMode (sump_low, INPUT_PULLUP);
  pinMode (sump_high, INPUT_PULLUP);
  pinMode (biofilter_low, INPUT_PULLUP);
  pinMode (biofilter_high, INPUT_PULLUP);
  pinMode (flowPin, INPUT_PULLUP);
  pinMode (biofilterLevel, INPUT_PULLUP);
  pinMode (sumpLevel, INPUT_PULLUP);
  pinMode (A1_Low_Level, INPUT_PULLUP);
  pinMode (A1_High_Level, INPUT_PULLUP);
  pinMode (growoutSump, INPUT_PULLUP);
  pinMode (POWER, INPUT_PULLUP);

  FULLSTOP_state = 1;
  override_state = 1;
  activepump = 2;
  depthstatusSump = 1;
  depthstatusBiofilter = 1;
  go_state = 0;
  dht.begin();
  gprs.begin(19200);
  Serial.begin(19200);
  /*
    lcd.begin(16, 2);
    lcd.print("HI CHRIS");
    lcd.setCursor(0, 1);
    lcd.print("GROW OUT CONTROL-DOME 1");
  */
  delay(5000);

  wdt_reset();
}

void POWER_UP()
{
  pinMode(9, OUTPUT);
  digitalWrite(9, LOW);
  delay(1000);
  digitalWrite(9, HIGH);
  delay(2000);
  digitalWrite(9, LOW);
  delay(3000);
}

void startsms()
{
  gprs.println("AT+CMGF=1\r"); // Set the shield to SMS mode
  delay(100);
  gprs.println("AT+CMGS = \"+27829729702\"");
  delay(100);
}

void endsms()
{
  gprs.print((char)26);//the ASCII code of the ctrl+z is 26 (required according to the datasheet)
  delay(100);
  gprs.println();
}

void tempreport()
{

  sensors.requestTemperatures(); // Send the command to get temperatures
  gprs.print("Ambient humidity: ");
  gprs.print(ambientH);
  gprs.println(" %");
  gprs.print("Ambient temp: ");
  gprs.print(ambientT);
  gprs.println("C ");
  gprs.print("Dome humidity: ");
  gprs.print(domeH);
  gprs.println(" %");
  gprs.print("Dome temp: ");
  gprs.print(domeT);
  gprs.println("C ");
  gprs.print("Main tank temp:  ");
  gprs.print(sensors.getTempCByIndex(0));
  gprs.println("C");
}

void timereport()
{

  DateTime now = RTC.now();
  gprs.print(now.year(), DEC);
  gprs.print('/');
  gprs.print(now.month(), DEC);
  gprs.print('/');
  gprs.print(now.day(), DEC);
  gprs.print(' ');
  if (now.hour() < 10)
  {
    gprs.print("0");
  }
  gprs.print(now.hour(), DEC);
  gprs.print(':');
  if (now.minute() < 10) {
    gprs.print("0");
  }
  gprs.print(now.minute(), DEC);
  gprs.print(':');
  if (now.second() < 10)
  {
    gprs.print("0");
  }
  gprs.print(now.second(), DEC);
  gprs.println();
  delay(100);


}


void smsReport(byte &isSomethingWrong)
{

  inchar = gprs.read();
  if (inchar == '/')
  {
    inchar = gprs.read();

    switch (inchar)
    {
      case 'r':
        {
          startsms();

          if (error == 1)//there is an error
          {
            gprs.println(mess2);
            delay(50);

            gprs.print("Sump: ");
            if (sumpError == 0)
            {
              gprs.println("OK");
            } else
            {
              gprs.println("ERROR");
            }
            delay(50);

            gprs.print("Biofilter: ");
            if (biofilterError == 0)
            {
              gprs.println("OK");
            } else
            {
              gprs.println("ERROR");
            }
            delay(50);

            gprs.print("A1 LOW: ");
            if (A1_Low_Error == 0)
            {
              gprs.println("OK");
            } else
            {
              gprs.println("ERROR");
            }
            delay(50);

            gprs.print("A1 HIGH: ");
            if (A1_High_Error == 0)
            {
              gprs.println("OK");
            } else
            {
              gprs.println("ERROR");
            }
            delay(50);

            gprs.print("Growout Sump: ");
            if (growoutSumpError == 0)
            {
              gprs.println("OK");
            } else
            {
              gprs.println("ERROR");
            }
            delay(50);

            gprs.print("POWER: ");
            if (POWERError == 0)
            {
              gprs.println("ON");
            } else
            {
              gprs.println("OFF");
            }

            delay(50);

            gprs.print("BLOWER: ");
            if (blower_state == 1)
            {
              gprs.println("ON");
            } else
            {
              gprs.println("OFF");
            }
          } else
          {
            gprs.println(mess1);
            tempreport();
          }
          timereport();
          delay(100);
          endsms();
          Serial.println("Report sent.");
          isSomethingWrong = 0;

          break;
        }
      case 'f':
        {
          startsms();
          gprs.print("Sump: ");
          if (sumpError == 0)
          {
            gprs.println("OK");
          } else
          {
            gprs.println("ERROR");
          }
          delay(50);

          gprs.print("Biofilter: ");
          if (biofilterError == 0)
          {
            gprs.println("OK");
          } else
          {
            gprs.println("ERROR");
          }
          delay(50);

          gprs.print("A1 LOW: ");
          if (A1_Low_Error == 0)
          {
            gprs.println("OK");
          } else
          {
            gprs.println("ERROR");
          }
          delay(50);

          gprs.print("A1 HIGH: ");
          if (A1_High_Error == 0)
          {
            gprs.println("OK");
          } else
          {
            gprs.println("ERROR");
          }
          delay(50);

          gprs.print("Growout Sump: ");
          if (growoutSumpError == 0)
          {
            gprs.println("OK");
          } else
          {
            gprs.println("ERROR");
          }
          delay(50);

          gprs.print("POWER: ");
          if (POWERError == 0)
          {
            gprs.println("OK");
          } else
          {
            gprs.println("ERROR");
          }
          endsms();

          break;
        }
      case 'h':
        {
          startsms();
          gprs.println("/r: system check");
          gprs.println("/f: error only");
          gprs.println("/t: temp");
          gprs.println("/b1: blower on");
          gprs.println("/b0: blower off");
          gprs.println("/bz: blower interval = 10 min");
          gprs.println("/bx: blower interval = 20 min");
          gprs.println("/bc: blower interval = 30 min");
          gprs.println("/bv: blower always on");
          gprs.println("/bq: blower always off");
          /*
            gprs.println("/z#: cancel error message");
            gprs.println("1: sump");
            gprs.println("2: bio");
            gprs.println("3: A1 High");
            gprs.println("4: A1 LOW");
          */
          endsms();

          break;
        }
      case 't':
        {
          startsms();
          tempreport();
          timereport();
          endsms();

          break;
        }
      case 'b':
        {
          // Serial.println("blower");

          inchar = gprs.read();
          switch (inchar)
          {
            case '1':
              {
                Serial.println(blower_state);
                //blower_state = 1;
                Serial.println(blower_state);
                // previousBlower = millis();

                break;
              }
            case '0':
              {
                Serial.println(blower_state);
                //blower_state = 0;
                Serial.println(blower_state);
                //                previousBlower = millis();
                Serial.println("blower off");
                break;
              }
            case 'z':
              {
                // blower_interval = 600000;
                // previousBlower = millis();
                Serial.println("blower off");
                break;
              }
            case 'x':
              {
                //  blower_interval = 1200000;
                //previousBlower = millis();
                //Serial.println("blower off");
                break;
              }
            case 'c':
              {
                //blower_interval = 1800000;
                //previousBlower = millis();
                Serial.println("blower off");
                break;
              }
          }

        case 'z':
          {
            inchar = gprs.read();
            switch (inchar)
            case '1':
            sumpWarning = 0;
            break;
          case '2':
            bioWarning = 0;
            break;
          case '3':
            A1_HighWarning = 0;
            break;
          case '4':
            A1_LowWarning = 0;
            break;

          }
        }
    }
  }
}
void smsReportSerial(byte &isSomethingWrong)
{

  inchar = Serial.read();
  if (inchar == '/')
  {
    inchar = Serial.read();

    switch (inchar)
    {
      case 'r':
        {
          startsms();

          if (error == 1)//there is an error
          {
            isSomethingWrong = 0;
            Serial.println(mess2);
            delay(100);
            Serial.print("Sump: ");
            delay(100);
            if (sumpError == 0)
            {
              Serial.println("OK");
            } else
            {
              Serial.println("ERROR");
            }
            Serial.print("Biofilter: ");
            if (biofilterError == 0)
            {
              Serial.println("OK");
            } else
            {
              Serial.println("ERROR");
            }
            Serial.print("A1 LOW: ");
            if (A1_Low_Error == 0)
            {
              Serial.println("OK");
            } else
            {
              Serial.println("ERROR");
            }
            Serial.print("A1 HIGH: ");
            if (A1_High_Error == 0)
            {
              Serial.println("OK");
            } else
            {
              Serial.println("ERROR");
            }
            Serial.print("Growout Sump: ");
            delay(100);
            if (growoutSumpError == 0)
            {
              Serial.println("OK");
            } else
            {
              Serial.println("ERROR");
            }
            Serial.print("POWER: ");
            delay(100);
            if (POWERError == 0)
            {
              Serial.println("OK");
            } else
            {
              Serial.println("ERROR");
            }
          } else
          {
            Serial.println(mess1);
          }
          delay(100);
          tempreport();
          timereport();
          endsms();

          break;
        }
      case 'h':
        {
          startsms();
          Serial.println("/r: report");
          Serial.println("/z#: cancel error message");
          Serial.println("1: sump");
          Serial.println("2: bio");
          Serial.println("3: A1 High");
          Serial.println("4: A1 LOW");

          endsms();

          break;
        }
      case 't':
        {
          startsms();
          tempreport();
          timereport();
          endsms();

          break;
        }
      case 'z':
        {
          inchar = Serial.read();
          switch (inchar)
          case '1':
          sumpWarning = 0;
          break;
        case '2':
          bioWarning = 0;
          break;
        case '3':
          A1_HighWarning = 0;
          break;
        case '4':
          A1_LowWarning = 0;
          break;

        }
    }
  }
}


void errorReport(byte &location,  byte &errorState)
{
  if (errorState == 0)//if problem is over
  {
    startsms();

    switch (location)
    {
      case 41:
        gprs.println("BIOFILTER OK");
        break;
      case 42:
        gprs.println("SUMP OK");
        break;
      case 43:
        gprs.println("A1 OK");
        break;
      case 44:
        gprs.println("A1 OK");
        break;
      case 45:
        gprs.println("POWER ON");
        break;
      case 47:
        gprs.println("GROWOUT SUMP OK");
        break;
    }
    //tempreport();
    timereport();//fill in the time details
    endsms();
  } else if (errorState == 1)//there is a problem
  {
    startsms();
    gprs.println("Uh oh");
    delay(100);
    switch (location) //report where the problem is
    {
      case 41:
        gprs.println("BIOFILTER HIGH");
        break;
      case 42:
        gprs.println("SUMP HIGH");
        break;
      case 43:
        gprs.println("A1 LOW");
        break;
      case 44:
        gprs.println("A1 HIGH");
        break;
      case 45:
        gprs.println("POWER OFF ");
        break;
      case 47:
        gprs.println("GROWOUT SUMP HIGH");
        break;
    }
    //tempreport();
    timereport();//fill in the time details
    endsms();
  }

  Serial.println("Text Sent.");
}




byte errorCheck(byte location, byte &errorState, byte &preverrrorState, unsigned long &CURRENT_timer, unsigned long &PREVIOUS_timer)
{


  CURRENT_timer = millis();//start the timer for reporting an error
  ok_timer = millis();
  errorState = digitalRead (location);
  
    
    int reading = digitalRead(location);

    // check to see if you just pressed the button
    // (i.e. the input went from LOW to HIGH),  and you've waited
    // long enough since the last press to ignore any noise:

    // If the switch changed, due to noise or pressing:
    if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        error = 1;
        if (errorState != preverrrorState)
    {
        Serial.println("error different state");
        errorReport(location, errorState);//report the error
        PREVIOUS_timer = millis();
      }
    }else if (errorState == preverrrorState)
    {


      if (CURRENT_timer - PREVIOUS_timer > interval_10s)
      {
        errorReport(location, errorState);//report the error
        PREVIOUS_timer = millis();
      }
    }
    }
if (errorState == LOW)
  {
    if (errorState != preverrrorState)
    {
      if (ok_timer - lastok_timer > interval_10s)
      {
        errorState = 0;//changes the error back to ok
        //errorReport(location, errorState);
        lastok_timer = millis();
      }
    } else if (errorState == preverrrorState)
    {

    }
  }
    lastButtonState = reading;
    
  preverrrorState = errorState;
  
/*
  if (errorState == HIGH)
  {
    error = 1;

    if (errorState != preverrrorState)
    {
      if (ok_timer - lastok_timer > interval_60s)
      {
        Serial.println("error different state");
        errorReport(location, errorState);//report the error
        PREVIOUS_timer = millis();
      }
    } else if (errorState == preverrrorState)
    {


      if (CURRENT_timer - PREVIOUS_timer > interval_20min)
      {
        errorReport(location, errorState);//report the error
        PREVIOUS_timer = millis();
      }
    }
  }
  if (errorState == LOW)
  {
    if (errorState != preverrrorState)
    {
      if (ok_timer - lastok_timer > interval_10s)
      {
        errorState = 0;//changes the error back to ok
        errorReport(location, errorState);
        lastok_timer = millis();
      }
    } else if (errorState == preverrrorState)
    {

    }
  }





  preverrrorState = errorState;

*/
}
}
void flowCheck()
{
  if ((millis() - flowTimer) > interval_5s)
  {
    if (depthstatusSump == 1 && flowState == 0)
    {
      FULLSTOP_state = 1;
    }
  }
}
void lcd_control(char device, byte state)
{
  //  lcd.setCursor(0, 0);
  //lcd.print(device);
  //lcd.setCursor(0, 1);
  if (state == 1)
  {
    //lcd.print(" is on");
  } else if (state == 0)
  {
    //lcd.print(" is off");
  }
}

void mech_control(byte relay, byte device_state)
{

  if (device_state == 1)
  {
    digitalWrite(relay, HIGH);
  } else if (device_state == 0)
  {
    digitalWrite(relay, LOW);
  }

}
void depthsump()
{
  if (digitalRead(sump_low) == LOW)
  {
    depthstatusSump = 0;
  }
  if (digitalRead(sump_high) == HIGH)
  {
    depthstatusSump = 1;
    flowTimer = millis();
  }



}

void depthbio()
{
  if (digitalRead(biofilter_low) == LOW)
  {
    depthstatusBiofilter = 0;
  }
  if (digitalRead(biofilter_high) == HIGH)
  {
    depthstatusBiofilter = 1;
  }
}



void manual_control()
{
  if (depthstatusSump == 1)
  {
    fade(go_led, 800);
  } else
  { fade(go_led, 3000);
  }
  if (millis() - previousmillis > override_timeout)

  {
    override_state = 0;
  }

  pump1_buttonState = digitalRead(pump1_button);


  if (pump1_buttonState != pump1_lastButtonState)
  {
    if (pump1_buttonState == HIGH)
    {
      if (pump1_state == 0)
      {
        pump1_state = 1;
        digitalWrite(pump1_led, HIGH);
        Serial.println("pump1 on");
        Serial.print("active pump: ");
        Serial.println(activepump);
      } else if (pump1_state == 1)
      {
        pump1_state = 0;
        digitalWrite(pump1_led, LOW);
        Serial.println("pump1 off");
        Serial.print("active pump: ");
        Serial.println(activepump);
      }
    } else
    {
    }
    delay(50);
  }

  pump1_lastButtonState = pump1_buttonState;

  //////////////////////////////////////////////////////////////////////////
  pump2_buttonState = digitalRead(pump2_button);


  if (pump2_buttonState != pump2_lastButtonState)
  {
    if (pump2_buttonState == HIGH)
    {
      if (pump2_state == 0)
      {
        pump2_state = 1;
        digitalWrite(pump2_led, HIGH);
        Serial.println("pump2 on");
        Serial.print("active pump: ");
        Serial.println(activepump);
      } else if (pump2_state == 1)
      {
        pump2_state = 0;
        digitalWrite(pump2_led, LOW);
        Serial.println("pump2 off");
        Serial.print("active pump: ");
        Serial.println(activepump);

      }
    } else
    {
    }
    delay(50);
  }

  pump2_lastButtonState = pump2_buttonState;
  ///////////////////////////////////////////////////////////////////////////
  /*
    blower_buttonState = digitalRead(blower_button);


    if (blower_buttonState != blower_lastButtonState)
    {
     if (blower_buttonState == HIGH)
     {
       if (blower_state == 1)
       {
         blower_state = 0;
         digitalWrite(blower_led, LOW);

         Serial.print("blower_state");
         Serial.println(blower_state);
       } else if (blower_state == 0)
       {
         blower_state = 1;
         digitalWrite(blower_led, HIGH);

         Serial.print("blower_state");
         Serial.println(blower_state);

       }
     } else
     {

     }
     delay(50);
    }

    blower_lastButtonState = blower_buttonState;
  */
  //////////////////////////////////////////////////////////////////////////
  uvlight_buttonState = digitalRead(uvlight_button);


  if (uvlight_buttonState != uvlight_lastButtonState)
  {
    if (uvlight_buttonState == HIGH)
    {
      if (uvlight_state == 1)
      {
        uvlight_state = 0;
        digitalWrite(uvlight_led, LOW);
      } else if (uvlight_state == 0)
      {
        uvlight_state = 1;
        digitalWrite(uvlight_led, HIGH);
      }
    } else
    {

    }
    delay(50);
  }

  uvlight_lastButtonState = uvlight_buttonState;

}

void debug()
{
  delay(2000);
  /*
    Serial.println("sump error state ");
    Serial.println(growoutSumpError);
    Serial.println(PREVgrowoutSumpError);
    Serial.println("biofilterLevel state ");
    Serial.println(biofilterError);
    Serial.println(PREVbiofilterError);
    Serial.println("PREVIOUSerrorState");
    //Serial.println(PREVIOUSerrorState);

     Serial.println("all good");
      Serial.print("errorState");
    Serial.println(errorState);
            Serial.print("PREVIOUSerrorState");
    Serial.println(PREVIOUSerrorState);
  */
  Serial.print("sumpstatus");
  Serial.println(depthstatusSump);
  Serial.println("biofilter");
  Serial.println(depthstatusBiofilter);
  Serial.println("36");

  Serial.println(digitalRead(36));
  Serial.println("37");

  Serial.println(digitalRead(37));
  Serial.println("38");

  Serial.println(digitalRead(38));
  Serial.println("39");

  Serial.println(digitalRead(39));
  Serial.println("40");

  Serial.println(digitalRead(40));
  Serial.println("41");

  Serial.println(digitalRead(41));
  Serial.println("42");

  Serial.println(digitalRead(42));
  Serial.println("43");

  Serial.println(digitalRead(43));
  Serial.println("44");

  Serial.println(digitalRead(44));
  Serial.println("47");

  Serial.println(digitalRead(47));

}

void fade(int led, int period)
{

  time = millis();
  value = 128 + 127 * cos(2 * PI / period * time);
  value2 = 128 + 127 * cos(2 * PI / period * (displace - time));
  analogWrite(led, value);
}

void nominal()
{
  wdt_reset();

  depthbio();
  pump2_buttonState = digitalRead(pump2_button);



  if (pump2_buttonState != pump2_lastButtonState)
  {
    if (pump2_buttonState == HIGH)
    {
      if (activepump == 2)
      {

      } else if (activepump == 1)
      {
        activepump = 2;

        Serial.print("active pump: ");
        Serial.println(activepump);
      }
    } else
    {
    }
    delay(50);
  }

  pump2_lastButtonState = pump2_buttonState;

  ///////////////////////////////////////////////
  pump1_buttonState = digitalRead(pump1_button);


  if (pump1_buttonState != pump1_lastButtonState)
  {
    if (pump1_buttonState == HIGH)
    {
      if (activepump == 1)
      {

      } else if (activepump == 2)
      {
        activepump = 1;

        Serial.print("active pump: ");
        Serial.println(activepump);
      }
    } else
    {
    }
    delay(50);
  }

  pump1_lastButtonState = pump1_buttonState;
  /////////////////////////////////////////////////////////

  if (depthstatusBiofilter == 1)
  {
    biofilterPump_state = 1;

  } else if (depthstatusBiofilter == 0)
  {
    biofilterPump_state = 0;
  }


  if (depthstatusSump == 1)
  {
    uvlight_state = 1;
    fade(uvlight_led, 1000);
    //blower_state = 1;
    fade(blower_led, 1000);
    fade(go_led, 800);

    if (activepump == 1) {
      pump1_state = 1;
      fade(pump1_led, 1000);
      pump2_state = 0;
      analogWrite(pump2_led, LOW);

    } else if (activepump == 2)
    {
      pump1_state = 0;
      analogWrite(pump1_led, LOW);
      pump2_state = 1;
      fade(pump2_led, 1000);
    }
  } else if (depthstatusSump == 0)
  {
    uvlight_state = 0;
    fade(uvlight_led, 4000);
    // blower_state = 1;
    fade(blower_led, 1000);
    fade(go_led, 3000);
    if (activepump == 1) {
      pump1_state = 0;
      pump2_state = 0;
      fade(pump1_led, 4000);
      analogWrite(pump2_led, LOW);
    } else if (activepump == 2)
    {
      pump1_state = 0;
      pump2_state = 0;
      fade(pump2_led, 4000);
      analogWrite(pump1_led, LOW);

    }
  }
}

void loop()
{
  wdt_reset();

  /*
    DateTime now = RTC.now();
    if ((now.hour() == 7) && (now.minute() == 30) && (now.second() < 2))
    { smsReport(error);
    }
    if ((now.hour() == 15) && (now.minute() == 30) && (now.second() < 2))
    { smsReport(error);
    }
    if ((now.hour() == 21) && (now.minute() == 30) && (now.second() < 2))
    { smsReport(error);
    }
  */
  Serial.println(domeH);
  
  if (gprs.available() > 0)
  {

    smsReport(error);
  }
  /*
    if (Serial.available() > 0)
    {

      smsReportSerial(error);
    }
  */
  //debug();


  depthsump();
  depthbio();

  //errorCheck(sumpLevel, sumpError, PREVsumpError, CURRENT_sump, PREVIOUS_sump);
  //errorCheck(biofilterLevel, biofilterError, PREVbiofilterError, CURRENT_biofilter, PREVIOUS_biofilter);
  errorCheck(growoutSump, growoutSumpError, PREVgrowoutSumpError, CURRENT_growoutSump, PREVIOUS_growoutSump);
  //errorCheck(A1_Low_Level, A1_Low_Error, PREVIOUS_A1_High_error CURRENT_A1_Low, PREVIOUS_A1_Low);
  //errorCheck(A1_High_Level, A1_High_Error, PREVIOUS_A1_High_error, CURRENT_A1_High, PREVIOUS_A1_High);
  //errorCheck(POWER, POWERError, PREVPOWERError, CURRENT_power, PREVIOUS_power);

  mech_control(biofilterPump_relay, biofilterPump_state);
  mech_control(pump1_relay, pump1_state);
  mech_control(pump2_relay, pump2_state);
  mech_control(blower_relay, blower_state);
  mech_control(uvlight_relay, uvlight_state);


  

  if (blower_state == 1)
  {
    blowerOfftime = millis();
  } else if (blower_state == 0)
  {
    blowerOntime = millis();
  }

  if (millis() - blowerOntime > blowerOninterval)
  {
    blower_state = 0;
    //Serial.println("blower off");
    //Serial.println(blowerOntime);
  } else if (millis() - blowerOfftime > blowerOffinterval)
  {
    blower_state = 1;
    //Serial.println("blower on");
    //Serial.println(blowerOfftime);
  }




  //flowCheck();
  ////////////////////////////////////////////////////////////////////
  /*
    FULLSTOP_buttonState = digitalRead(FULLSTOP_button);


    if (FULLSTOP_buttonState != FULLSTOP_lastButtonState)
    {

      if (FULLSTOP_buttonState == HIGH)
      {
        if (FULLSTOP_state == 1)
        {
          FULLSTOP_state = 0;
          Serial.println("GO!!");
          digitalWrite(FULLSTOP_led, LOW);


        } else if (FULLSTOP_state == 0)
        {
          FULLSTOP_state = 1;
          Serial.println("FULL STOP");
          digitalWrite(FULLSTOP_led, HIGH);
        }
      } else
      {

      }
      delay(50);
    }
    FULLSTOP_lastButtonState = FULLSTOP_buttonState;
  */
  //////////////////////////////////////////////////////////
  go_buttonState = digitalRead(go_button);


  if (go_buttonState != go_lastButtonState)
  {

    if (go_buttonState == HIGH)
    {
      if (FULLSTOP_state == 1)
      {
        FULLSTOP_state = 0;
        Serial.println("GO!!!");
        digitalWrite(FULLSTOP_led, LOW);


      } else if (FULLSTOP_state == 0)
      {
        if (depthstatusSump == 1)
        {
          depthstatusSump = 0;

        } else if (depthstatusSump == 0)
        {
          depthstatusSump = 1;
        }

      }
    } else
    {

    }
    delay(50);
  }
  go_lastButtonState = go_buttonState;
  ////////////////////////////////////////////////////////////////////

  override_buttonState = digitalRead(override_button);


  if (override_buttonState != override_lastButtonState)
  {
    if (override_buttonState == HIGH)
    {
      if (override_state == 1)
      {
        override_state = 0;
        Serial.println("OVERRIDE OFF");


      } else if (override_state == 0)
      {
        override_state = 1;

        Serial.println("OVERRIDE ON");
        digitalWrite(pump1_led, pump1_state);
        digitalWrite(pump2_led, pump2_state);
        digitalWrite(blower_led, blower_state);
        digitalWrite(uvlight_led, uvlight_state);
        previousmillis = millis();

      }
    } else
    {

    }
    delay(50);
  }

  override_lastButtonState = override_buttonState;


  if (FULLSTOP_state == 1)
  {
    pump1_state = 0;
    pump2_state = 0;
    //blower_state = 0;
    override_state = 0;
    uvlight_state = 0;
    analogWrite(pump1_led, LOW);
    analogWrite(pump2_led, LOW);
    analogWrite(blower_led, LOW);
    analogWrite(uvlight_led, LOW);
    analogWrite(override_led, LOW);
    fade(go_led, 300);

  } else {

    if (override_state == 1) {
      manual_control();
      fade(override_led, 500);



    } else if (override_state == 0)
    {
      nominal();
      fade(override_led, 4000);
    }
  }
}


