#include <OneWire.h>
#include <DallasTemperature.h>
#include <Ethernet.h> //Load Ethernet Library
#include <EthernetUdp.h> //Load UDP Library
#include <SPI.h> //Load the SPI Library
#include "DHT.h"
#include <avr/wdt.h>

#define DHTTYPE DHT22
#define sump_low 9
#define sump_high 3//
#define biofilter_low A5
#define biofilter_high 5//
#define DHTambient 6
#define DHTdome 7
#define ONE_WIRE_BUS 8
#define sumpWarn 2
#define pump A0//
#define blower A1//
#define uv A2//
#define bioPump A3//
#define growoutWarn A4
#define power 4

OneWire oneWire(ONE_WIRE_BUS);
DHT dht_ambient(DHTambient, DHTTYPE);
DHT dht_dome(DHTdome, DHTTYPE);

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

byte mac[] = { 0x90, 0xA1, 0xDA, 0x00, 0x59, 0x09 };

byte gateway[] = { 192, 168, 0, 254 };
byte subnet[] = { 255, 255, 255, 0 };
unsigned int localPort = 5000; //Assign a Port to talk over
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
String datReq; //String for our data
int packetSize; //Size of Packet



int buttonState1;             // the current reading from the input pin
int lastButtonState1 = HIGH;   // the previous reading from the input pin
int buttonState2;             // the current reading from the input pin
int lastButtonState2 = HIGH;
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime1 = 0;
long lastDebounceTime2 = 0; // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

EthernetUDP Udp; //Define UDP Object

unsigned long resetInterval = 120000;
unsigned long resetTimer = 0;
unsigned long blowerOntime = 0;
unsigned long blowerOfftime = 0;
long blowerOninterval = 3000000;
long blowerOffinterval = 600000;
//long blowerOffinterval = 5000;
//long blowerOninterval = 10000;


byte blower_state = 1;
byte depthstatusSump = 1;
byte depthstatusBiofilter = 1;
byte watchDog = 1;




void setup() {
  Serial.begin(19200);

  Serial.println("Hi Chris");

  pinMode(DHTambient, INPUT);
  pinMode(DHTdome, INPUT);
  pinMode(ONE_WIRE_BUS, INPUT);
  pinMode(sumpWarn, INPUT_PULLUP);
  pinMode(growoutWarn, INPUT_PULLUP);

  pinMode(pump, OUTPUT);
  pinMode(blower, OUTPUT);
  pinMode(uv, OUTPUT);
  pinMode(bioPump, OUTPUT);
  pinMode(sump_low, INPUT_PULLUP);
  pinMode(sump_high, INPUT_PULLUP);
  pinMode (biofilter_low, INPUT_PULLUP);
  pinMode (biofilter_high, INPUT_PULLUP);
  pinMode (power, INPUT_PULLUP);
  sensors.begin();
  dht_dome.begin();
  dht_ambient.begin();

  Ethernet.begin(mac); //Initialize Ethernet
  Udp.begin(localPort); //Initialize Udp
  printIPAddress();
  wdt_enable(WDTO_8S);





}

void printIPAddress()
{
  Serial.print("My IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }

  Serial.println();
}


void loop()
{


  //Serial.println(watchDog);

  if (digitalRead(sump_low) == LOW)
  {
    depthstatusSump = 0;
  }
  if (digitalRead(sump_high) == HIGH)
  {
    depthstatusSump = 1;
  }

  if (depthstatusSump == 1)
  {
    digitalWrite(pump, HIGH);
    digitalWrite(uv, HIGH);
  } else if (depthstatusSump == 0)
  {
    digitalWrite(pump, LOW);
    digitalWrite(uv, LOW);
  }
  if (digitalRead(biofilter_low) == LOW)
  {
    depthstatusBiofilter = 0;
  }
  if (digitalRead(biofilter_high) == HIGH)
  {
    depthstatusBiofilter = 1;
  }
  if (depthstatusBiofilter == 1)
  {
    digitalWrite(bioPump, HIGH);

  } else if (depthstatusBiofilter == 0)
  {
    digitalWrite(bioPump, LOW);

  }


  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);
  }

  if (blower_state == 1)
  {
    digitalWrite(blower, HIGH);
  } else if (blower_state == 0)
  {
    digitalWrite(blower, LOW);
  }
  packetSize = Udp.parsePacket(); //Read theh packetSize

  if (packetSize > 0) { //Check to see if a request is present
    //Serial.println("data requested");
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Reading the data request on the Udp
    String datReq(packetBuffer); //Convert packetBuffer array to string datReq

    if (datReq == "temp") {
      sensors.requestTemperatures(); // Send the command to get temperatures
      float sumptemp = sensors.getTempCByIndex(0);
      float tanktemp = sensors.getTempCByIndex(1);
      float domeH = dht_dome.readHumidity();
      float domeAirtemp = dht_dome.readTemperature();
      float ambientH = dht_ambient.readHumidity();
      float ambientAirtemp = dht_ambient.readTemperature();
      //Serial.println("got request");
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());  //Initialize Packet send

      Udp.print(sumptemp);
      Udp.print(" ");
      Udp.print(tanktemp);
      Udp.print(" ");
      Udp.print(domeAirtemp);
      Udp.print(" ");
      Udp.print(domeH);
      Udp.print(" ");
      Udp.print(ambientAirtemp);
      Udp.print(" ");
      Udp.print(ambientH);
      Udp.print(" ");
      Udp.print(digitalRead(pump));
      Udp.print(" ");
      Udp.print(digitalRead(blower));
      Udp.endPacket(); //Packet has been sent
    }

    if (datReq == "error") {
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());  //Initialize Packet send
      Udp.print(digitalRead(sumpWarn));
      Udp.print(" ");
      Udp.print(digitalRead(growoutWarn));
      //Udp.print(" ");
      //Udp.print(digitalRead(power));
      Udp.endPacket(); //Packet has been sent
      resetTimer = millis();

    }
    if (datReq == "blowerOn") {
      blower_state = 1;
    }
    if (datReq == "blowerOff") {
      blower_state = 0;
    }

    if (datReq == "sumpPumpOn") {
      depthstatusSump = 1;
    }

    if (datReq == "sumpPumpOff") {
      depthstatusSump = 0;
    }

    if (datReq == "bioPumpOn") {
      depthstatusBiofilter = 1;
    }

    if (datReq == "bioPumpOff") {
      depthstatusBiofilter = 0;
    }


  }
    memset(packetBuffer, 0, UDP_TX_PACKET_MAX_SIZE);
  
  if (watchDog == 1)
  {
    wdt_reset();

  } else if (watchDog == 0) {

  }

  if (millis() - resetTimer > resetInterval)
  {
    watchDog = 0;
  } else if (millis() - resetTimer < resetInterval)
  {
    watchDog = 1;

  }



}

