#include <DHT.h>

#include <EthernetServer.h>
#include <EthernetUdp.h>
#include <Dhcp.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <Dns.h>


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

#define DHTTYPE DHT22
#define DHTPIN 7
#define ONE_WIRE_BUS 2
#define pump 8
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
DHT dht(DHTPIN, DHTTYPE);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
byte switchState = 0;
byte lastswitchState;
byte mac[] = { 0x90, 0xA1, 0xDA, 0x00, 0x51, 0x09 };//IP.25
EthernetServer server(80);
String readString;

long previousMillis;
long interval_10min = 600000;
unsigned long pumpOffTime = 0;
unsigned long pumpOnTime = 0;

byte pumpState = 0;
byte pumpControl = 1;
EthernetUDP Udp; //Define UDP Object

void setup() {

  Serial.begin(19200); //Turn on Serial Port
  Ethernet.hostName("TUNNEL");

  sensors.begin();
  dht.begin();
  Ethernet.begin(mac); //Initialize Ethernet
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  Serial.println(Ethernet.getHostName());

  pinMode(pump, OUTPUT);
}
// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 100;
// the maximum length of paramters we accept
const int MAX_PARAM = 30;


// Example GET line: GET /?foo=bar HTTP/1.1
void processGet (const char * data)
{
  // find where the parameters start
  const char * paramsPos = strchr (data, '?');
  if (paramsPos == NULL)
    return;  // no parameters
  // find the trailing space
  const char * spacePos = strchr (paramsPos, ' ');
  if (spacePos == NULL)
    return;  // no space found
  // work out how long the parameters are
  int paramLength = spacePos - paramsPos - 1;
  // see if too long
  if (paramLength >= MAX_PARAM)
    return;  // too long for us
  // copy parameters into a buffer
  char param [MAX_PARAM];
  memcpy (param, paramsPos + 1, paramLength);  // skip the "?"
  param [paramLength] = 0;  // null terminator

  // do things depending on argument (GET parameters)

  if (strcmp (param, "pumpOn") == 0)
  {
    Serial.println (F("Activating pump"));

    pumpState = 1;
    Serial.println(pumpState);
  } else if (strcmp (param, "pumpOff") == 0)
  {
    Serial.println (F("Deactivating pump"));
    pumpState = 0;
    Serial.println(pumpState);

  } 
  
  if (strcmp (param, "controlOn")==0)
  {
    pumpControl = 1;
    Serial.println(pumpControl);
    Serial.println("ON MSG RECV");
  } else if (strcmp (param, "controlOff")==0)
  {
    pumpControl = 0;
        Serial.println(pumpControl);
    Serial.println("OFF MSG RECV");

  }

}  // end of processGet

// here to process incoming serial data after a terminator received
void processData (const char * data)
{
  Serial.println (data);
  if (strlen (data) < 4)
    return;

  if (memcmp (data, "GET ", 4) == 0)
    processGet (&data [4]);
}  // end of processData

bool processIncomingByte (const byte inByte)
{
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;
  switch (inByte)
  {
    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte
      if (input_pos == 0)
        return true;   // got blank line
      // terminator reached! process input_line here ...
      processData (input_line);
      // reset buffer for next time
      input_pos = 0;
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;
  }  // end of switch
  return false;    // don't have a blank line yet
} // end of processIncomingByte

void loop() {


  if (pumpControl == 1) {

    if (pumpState == 1)
    {
      digitalWrite(pump, HIGH);
      pumpOffTime = millis();
    } else if (pumpState == 0)
    {
      digitalWrite(pump, LOW);
      pumpOnTime = millis();
    }

    if (millis() - pumpOnTime > interval_10min)
    {
      pumpState = 0;

    } else if (millis() - pumpOffTime > interval_10min)
    {
      pumpState = 1;

    }

  } else if (pumpControl == 0) {
    digitalWrite(pump, LOW);
  }

  // listen for incoming clients
  EthernetClient client = server.available();
  if (client)
  {
    sensors.requestTemperatures(); // Send the command to get temperatures
    float temp1 = sensors.getTempCByIndex(0);
    float airtemp = dht.readTemperature();
    float humidity = dht.readHumidity();
    Serial.println(F("Client connected"));
    // an http request ends with a blank line
    boolean done = false;
    while (client.connected() && !done)
    {
      while (client.available () > 0 && !done)
        done = processIncomingByte (client.read ());
    }  // end of while client connected

    // send a standard http response header

    client.print(temp1);
    client.print(", ");
    client.print(airtemp);
    client.print(", ");
    client.print(humidity);
    client.print(", ");
    client.print(digitalRead(pump));
    client.print(", ");

    client.print(pumpControl);

    // give the web browser time to receive the data
    delay(10);
    // close the connection:
    client.stop();
    Serial.println(F("Client disconnected"));
  }  // end of got a new client



}



