#include <Ethernet.h>
#include <SPI.h>
//connection variables
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x00, 0xA8}; // mac address of ethernet shield
char serverName[] = "192.168.1.7"; 
//char serverName[] = "zafora.icte.uowm.gr"; 
int os[40];
int i;
int a;
int b;
EthernetClient client;
EthernetClient client2;
EthernetClient client3;
boolean startRead = false; // read data or not
boolean result;
boolean resultH;
boolean resultT;
boolean resultIL;
boolean resultM;
//sensor list
int MoistureSensorPin = 5;
int PhotocellPin = 2; // the cell and 10K pulldown are connected to a0
int HumidityPin = 3; //humidity sensor pin
int TemperaturePin = 4;
//variables for the internal clock
int year=0;
int month=0;
int day=0;
int hour=0;
int mi=0;
//OUTPUT LIST
#define VALVE 8
#define FAN 7
#define LED 6

//message outputs
float T;
double H;
int IL;
int M;
int F;
int V;
int L;


void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac);
  //outputs
  pinMode(FAN, OUTPUT);
  pinMode(VALVE, OUTPUT);
  pinMode(LED, OUTPUT);
  //inputs
  pinMode(PhotocellPin, INPUT);
  pinMode(MoistureSensorPin, INPUT);
  pinMode(HumidityPin, INPUT);
  pinMode(TemperaturePin, INPUT);
  result=false;
}


void loop() {
  if (year==0 && month==0 && day==0 && hour==0 && mi==0)
    {
      set_time();
    }
  else
    {
      if(mi%15==0)
        {
          set_time();
        }
      else
       { 
      timer();
      delay(1000);
        }  
  } 
  Serial.println("wra");
  Serial.println(hour);
  Serial.println(mi);  
  Serial.println();
  int WaterNeed = analogRead(MoistureSensorPin);
  int PhotocellReading = analogRead(PhotocellPin);
  double Humidity = analogRead(HumidityPin);
  int Temperature = analogRead(TemperaturePin);     
  //photocell check      
  if (PhotocellReading == 0){
    IL = 0;
  }
  else {
    IL = PhotocellReading;
  }
  //humidity check
  if ( Humidity == 0){
    H = 0;
  }
  else
  {  
    double voltageValue = ((4.82)*Humidity)/1023;
    double rh = (voltageValue - 0.788)/0.0314;
    H = rh; 
  }
  //temperature check
  if ( Temperature == 0){
    T= 0;
    }
  else
  {
    float VoltBoost = (Temperature *4.81); // convert 
    float Boost = (VoltBoost *100);//convert 2
    float Kelvin = (Boost/1023);//Kelvin
    float Celsius = Kelvin -275;//Celsius
    T= Celsius;
   }     
  //moisture sensor check
  if ( WaterNeed < 0 && WaterNeed >=1300){
    M=3;
  }
  else
  {
    if (WaterNeed<690)
    {
      M=0;
    }
    else
    {
      M=1;
    }
  }
  Serial.print("M:");
  Serial.println(M);
 connectAndRead();
 delay(250);
 client.stop();
 delay(250);
 client.flush();
 delay(500);
 //Led condition
 if (L==1)
   {
     digitalWrite(LED,HIGH);
   }
 else
   {
     digitalWrite(LED,LOW);
   }
   //fan condition
 if (F==1)
   {
     digitalWrite(FAN,HIGH);
   }
 else
   {
     digitalWrite(FAN,LOW);
   }
   //valve condition
  if (V==1)
   {
     digitalWrite(VALVE,HIGH);
   }
 else
   {
     digitalWrite(VALVE,LOW);
   }  
 //delay for devices optimization..then send data
 delay(250);
 connectAndSend();
 delay(250);
 client2.stop();
 delay(500);
 client2.flush();
  
 
  delay(54000);
}

void connectAndRead(){
  if (client.connect(serverName, 80)) {
    Serial.println("connect 1");
String main_data="device_id=1&device_password=bda5accf070d5938804296ecaab15978d2c45e9c&option=1";
 //client.println("POST /~ictest00120/arduino.php HTTP/1.1");
 //client.println("Host: zafora.icte.uowm.gr");
client.println("POST /guardian/arduino.php HTTP/1.1");
client.println("Host: 192.168.1.7");
 client.println("Content-Type: application/x-www-form-urlencoded");
 client.println("Connection: close");
 client.print("Content-Length: ");
 client.println(main_data.length());
 client.println();
 client.println(main_data);
 client.println();
delay(900);
memset(os, 0, 40);
i=0; 
int blank1=0;
while (client.connected())
      {
          if (client.available())
          {
            char c=client.read();
            if (startRead==false)
                {
                  if (c=='*')
                    {
                    startRead=true;
                    blank1=1;
                    }
                  else
                    { 
                      if (blank1==1)
                        {
                        client.stop();
                        delay(100);
                        client.flush();
                        delay(100);
                        }
                    }
                    
                }
              else 
                {
                  if (c !='@')
                    {
                    int y=atoi(&c);
                    os[i]=y;
                    Serial.print(y);
                    i++;
                    }
                  else
                    {
                    startRead=false;  
                    }  
                }
              
          }
        else
          {
           if (i==0)
           {
           os[i]=9; 
           }
          }
      }
     
     if (os[0]!=9)
        {
          if (i==3)
              {
                result=true;
              }
          else
              {
                b=1;
                for(a=3;a<=i-1;a=a+8)
                  {                  
                    if (os[a]==1)
                      {
                        float limit1=float(100*os[a+1] +10*os[a+2]+1*os[a+3]);
                        float limit2=float(100*os[a+4] +10*os[a+5]+1*os[a+6]);
                        if (T>=limit1 && T<=limit2)
                          {
                            resultT=true;
                          }
                        else
                          {
                            resultT=false;
                          }
                       if (b!=1)
                          {
                            if(os[a-1]==1)
                              {
                                result |=resultT;
                              }
                            else
                              {
                                result &=resultT;
                              }  
                          }
                      else
                          {
                            result=resultT;
                          }    
                      
                    b++;
                  }
                      else if (os[a]==2)
                      {
                        double limit1=double(100*os[a+1] +10*os[a+2]+1*os[a+3]);
                        double limit2=double(100*os[a+4] +10*os[a+5]+1*os[a+6]);
                        if (H>=limit1 && H<=limit2)
                          {
                            resultH=true;
                          }
                        else
                          {
                            resultH=false;
                          }
                       if (b!=1)
                          {
                            if(os[a-1]==1)
                              {
                                result |=resultH;
                              }
                            else
                              {
                                result &=resultH;
                              }  
                          }
                      else
                          {
                            result=resultH;
                          }    
                    b++;  
                    }
                      else if (os[a]==3)
                      {
                        int limit1=100*os[a+1] +10*os[a+2]+1*os[a+3];
                        int limit2=100*os[a+4] +10*os[a+5]+1*os[a+6];
                        if (IL>=limit1 && IL<=limit2)
                          {
                            resultIL=true;
                          }
                        else
                          {
                            resultIL=false;
                          }
                       if (b!=1)
                          {
                           if(os[a-1]==1)
                              {
                                result |=resultIL;
                              }
                            else
                              {
                                result &=resultIL;
                              }  
                          }
                      else
                          {
                            result = resultIL;
                          }    
                    b++;  
                    }
                      else
                      {
                        int limit1=(100*os[a+1] +10*os[a+2]+1*os[a+3]);
                        if (M==limit1)
                          {
                            resultM=true;
                          }
                        else
                          {
                            resultM=false;
                          }
                       if (b!=1)
                          {
                            if(os[a-1]==1)
                              {
                                result |=resultM;
                              }
                            else
                              {
                                result &=resultM;
                              }  
                        b++;  
                        }
                      else
                          {
                            result=resultM;
                          }    
                      }
                    Serial.println();
                    Serial.print(a);
                    Serial.print(":");
                    Serial.println(result);
                    Serial.print("rule");
                  Serial.println(os[a-1]);  
                  }
                 }
          Serial.println("final result:");
          Serial.println(result);
          if (result==true)
              {
               F=os[0];
               V=os[1];
               L=os[2];
              }
          else
            {
              F=0;
              V=0;
              L=0;
            }
       }
  }
 else
  {
    software_Reset();
  }
}



void connectAndSend(){
  if (client2.connect(serverName, 80)) {
    delay(1000);
    Serial.println("connected 2");
    String data2="device_id=1&device_password=bda5accf070d5938804296ecaab15978d2c45e9c&option=2";
    data2+="&temp=";
    data2+=(int)T;
    data2+="&hum=";
    data2+=(int)H;
    data2+="&somo=";
    data2+=M;
    data2+="&inli=";
    data2+=IL;
    data2+="&f=";
    data2+=F;
    data2+="&v=";
    data2+=V;
    data2+="&l=";
    data2+=L;
    data2+="&date=";
    data2+=year;
    data2+="-";
    data2+=month;
    data2+="-";
    data2+=day;
    data2+="&time=";
    data2+=hour;
    data2+=":";
    data2+=mi;
    data2+=":";
    data2+="00";
 //client2.println("POST /~ictest00120/arduino.php HTTP/1.1");
 //client2.println("Host: zafora.icte.uowm.gr");
 client2.println("POST /guardian/arduino.php HTTP/1.1");
 client2.println("Host: 192.168.1.7");
 client2.println("Content-Type: application/x-www-form-urlencoded");
 client2.println("Connection: close");
 client2.print("Content-Length: ");
 client2.println(data2.length());
 client2.println();
 client2.println(data2);
 client2.println();
delay(100);
    client2.stop();
    delay(100);
    client2.flush(); 
 Serial.println(data2);  
 }
  else
  {
    software_Reset();
  }
}


void set_time()
{
if (client3.connect(serverName, 80)) {
    delay(800);
String data3="device_id=1&device_password=bda5accf070d5938804296ecaab15978d2c45e9c&option=3";
 //client3.println("POST /~ictest00120/arduino.php HTTP/1.1");
 //client3.println("Host: zafora.icte.uowm.gr");
 client3.println("POST /guardian/arduino.php HTTP/1.1");
 client3.println("Host: 192.168.1.7");
  client3.println("Content-Type: application/x-www-form-urlencoded");
  client3.println("Connection: close");
  client3.print("Content-Length: ");
  client3.println(data3.length());
  client3.println();
  client3.println(data3);
  client3.println();
  memset(os, 0, 40);
  i=0;
 int blank3=0; 
while (client3.connected())
      {
          if (client3.available())
          {
            char c=client3.read();
            if (startRead==false)
                {
                  if (c=='*')
                    {
                    startRead=true;
                    blank3=1;
                    }
                  else
                    { 
                      if (blank3==1)
                        {
                        client3.stop();
                        delay(100);
                        client3.flush();
                        delay(100);
                        }
                    }
                    
                }
              else 
                {
                  if (c !='@')
                    {
                    int y=atoi(&c);
                    os[i]=y;
                    i++;
                    }
                  else
                    {
                    startRead=false;  
                    }  
                }
              
          }
      }
      year = (1000*os[0]+100*os[1]+10*os[2]+1*os[3]);
      month= (10*os[4]+1*os[5]);
      if (os[6]<=3 && os[7]<=9)
        {
        day=(10*os[6]+1*os[7]);
        }
      if (os[8]<=2 && os[9]<=9)
        {
          hour=(10*os[8]+1*os[9]); 
        }
     if (os[10]<=5 && os[11]<=9)
        {
          mi=(10*os[10]+1*os[11]); 
        }
       
  }
  else
  {
    software_Reset();
  }
}

void timer()
{
if (mi==59)
  {    
    mi=0;
    if (hour==23)
      {
        if (month==2)
          {
           if (month%4==0)
            {
            if (day==29)
              {
                month++;
                day=1;
              }
             else
              {
                day++;
              } 
            }
           else
            {
             if (day==28)
              {
                month++;
                day=1;
              }
             else
              {
                day++;
              }  
            } 
          }
       else if(month==1 || month==3 || month==5 || month==7 || month==8 ||month==10)
           {
             if (day==31)
              {
                month++;
                day=1;
              }
             else
              {
                day++;
              }
           }
      else if( month==4 ||month==6 || month==9 || month==11)
           {
              if (day==30)
              {
                month++;
                day=1;
              }
             else
              {
                day++;
              }
           }
      else
           {
            if (day==31)
              {
                year++;
                month=1;
                day=1;
              }
             else
              {
                day++;
              } 
           }     
    hour=0;  
    }
   else
    {
      hour++;
    } 
  }
 else
  {
    mi++;
  }  
}


void(* resetFunc) (void) = 0; //declare reset function @ address 0


void software_Reset() {
  Serial.println("problem");
  asm volatile ("  jmp 0");
  resetFunc();
}



