/////////////
//Libraries//
/////////////
#include <Time.h>
//#include <TimeLib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include <OneWire.h>
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"

#define DHTPIN 7         //Pin on which is DHT sensor conected
#define DHTYPE DHT22      //Type of DHT sensor(I tried program with DHT11 works the same)

const int chipSelect = 10; //cs or the save select pin from the sd shield is connected to 10.
RTC_DS1307 RTC;  //Real Time Clock variable


File dataFile;  //Used for using SD card, to write and read on the card 
DateTime now;

LiquidCrystal_I2C lcd(0x27, 16, 2);

DHT dht(DHTPIN, DHTYPE);   //Defining DHT sensor


//Variables used 
int shortDelay = 200;
float humidity = 0;
float tempCels = 0;
float niz[11];
float nizHumidity[11];
float midValue = 0;
float midValueHumidity = 0;
bool midValueBoolT = false;
bool midValueBoolH = false;
int i = 0;
int j = 0;


///////////
//Getters//
///////////
String getTemperature(){
  String txt = "TEMPERATURE:";
  txt.concat(String(tempCels, 0));
  txt.concat((char)223);
  txt.concat("C");
  return txt;
}

String getMidTemperature(float midValue){
  String txt = "TEMP/AVG:";
  txt.concat(String(midValue, 0));
  txt.concat((char)223);
  txt.concat("C");
  return txt;
}

String getHumidity(){
  return "  HUMIDITY:" +String(humidity, 0) + "%";
}

String getMidHumidity(float midValueHumidity){
  String txt = "HUM/AVG:";
  txt.concat(String(midValueHumidity, 0));
  txt.concat("%");
  return txt;
}


///////////////////////////////////////////
//method for reading data from dht sensor//
///////////////////////////////////////////
void readSensorData(){
  humidity = dht.readHumidity();
  tempCels = dht.readTemperature(); // dht.readTemperature(true); if you want to measure temp in farenheit 
}


///////////////////////////////
//printing temperature on LCD//
/////////////////////////////// 
void printLcdTemperature(){
  lcd.clear();
  lcd.setCursor(0,0);  
  lcd.print(getTemperature());
}

void printLcdMidTemperature(float midValue){
  lcd.setCursor(0,0);  
  lcd.print(getMidTemperature(midValue));
}

////////////////////////////
//humidity printing on LCD//
////////////////////////////  
void printLcdHumidity(){
  lcd.setCursor(0,1);
  lcd.print(getHumidity());
}

void printLcdMidHumidity(float midValueHumidity){
  lcd.setCursor(0,1);
  lcd.print(getMidHumidity(midValueHumidity));
}


void setup() {
  Serial.begin(9600);
  //setup clock
  Wire.begin();
  RTC.begin();
  //Look out for this part, uncoment it if you want to set time on your RTC 
  // following line sets the RTC to the date & time this sketch was compiled
    // uncomment it & upload to set the time, date and start run the RTC!
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  //check or the Real Time Clock is on
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    while(1){}
  }
//setup SD card
   Serial.print("Initializing SD card...");

  // see if the SD card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  //write down the date (year / month / day         prints only the start, so if the logger runs for sevenal days you only findt the start back at the begin.
    now = RTC.now();
    readSensorData();
    dataFile = SD.open("datalog.txt", FILE_WRITE);
    dataFile.print("Start logging on: ");
    dataFile.print(now.year(),DEC);
    dataFile.print('/');
    dataFile.print(now.month(),DEC);
    dataFile.print('/');
    dataFile.print(now.day(),DEC);
    dataFile.println(" ");
    dataFile.println("Celsius              Humidity              Time              Date");
    dataFile.close();
  
  lcd.clear();
  lcd.backlight();
  lcd.init();
  lcd.begin(16,2);

  dht.begin();
}

void loop() {

  readSensorData();
  //int minute, second;
  now = RTC.now();

if((now.minute() == 0 || now.minute() == 5 || now.minute() == 10 || now.minute() == 15 || now.minute() == 20 || now.minute() == 25 || now.minute() == 30 || now.minute() == 35 || now.minute() == 40 || now.minute() == 45 || now.minute() == 50 || now.minute() == 55) && now.second() < 5){
  dataFile = SD.open("datalog.txt",FILE_WRITE);

  if (dataFile) {
    dataFile.print(tempCels);
    dataFile.print("                 ");
    dataFile.print(humidity);
    dataFile.print("              ");
    dataFile.print(now.hour(),DEC);
    dataFile.print(":");
    dataFile.print(now.minute(),DEC);
    dataFile.print(":");
    dataFile.print(now.second(),DEC);
  dataFile.print("              ");
  dataFile.print(now.year(),DEC);
    dataFile.print('/');
    dataFile.print(now.month(),DEC);
    dataFile.print('/');
    dataFile.println(now.day(),DEC);
   
    dataFile.close();
    // print to the serial port too:
    Serial.println("data stored");
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
  delay(5000);
  }


// at this part you can change time when you want something to be saved, this can also be used if you are doing something else with RTC and if you want to do something at some exact time 
//this one is used to save data from sensor 
if((now.minute() == 3 || now.minute() == 8 || now.minute() == 13 || now.minute() == 18 || now.minute() == 23 || now.minute() == 28 || now.minute() == 33 || now.minute() == 38 || now.minute() == 43 || now.minute() == 48 || now.minute() == 53 || now.minute() == 58) && now.second() < 10){
  dataFile = SD.open("datalogB.txt",FILE_WRITE);

  if (dataFile) {
    dataFile.print(tempCels);
    dataFile.print(";");
    
    dataFile.close();
    // print to the serial port too:
    Serial.println("data stored");
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalogB.txt");
  }
  delay(10000);
  }

  if((now.minute() == 1 || now.minute() == 6 || now.minute() == 11 || now.minute() == 16 || now.minute() == 21 || now.minute() == 26 || now.minute() == 31 || now.minute() == 36 || now.minute() == 41 || now.minute() == 46 || now.minute() == 51 || now.minute() == 56) && now.second() < 10){
  dataFile = SD.open("datalogC.txt",FILE_WRITE);

  if (dataFile) {
    dataFile.print(humidity);
    dataFile.print(";");
    
    dataFile.close();
    // print to the serial port too:
    Serial.println("data stored");
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalogB.txt");
  }
  delay(10000);
  }


//citanje podataka
if((now.minute() == 2 || now.minute() == 7 || now.minute() == 12 || now.minute() == 17 || now.minute() == 22 || now.minute() == 27 || now.minute() == 32 || now.minute() == 37 || now.minute() == 42 || now.minute() == 47 || now.minute() == 52 || now.minute() == 57) && now.second() < 10){
   dataFile = SD.open("datalogB.txt",FILE_READ);
   if(dataFile){
    while(dataFile.available()){
      float x = dataFile.parseFloat();
      niz[i] = x;
      i++;
      Serial.print("Member: ");
      Serial.print(i-1);
      Serial.print(" is: ");
      Serial.println(niz[i-1]);
      if(i==11){
        niz[i] = x;
        i = 0;
        midValueBoolT = true;
      }
    }
    dataFile.close();
        
   }
   else{
    Serial.println("error opening file");
   }
   delay(10000);
}

if((now.minute() == 4 || now.minute() == 9 || now.minute() == 14 || now.minute() == 19 || now.minute() == 24 || now.minute() == 29 || now.minute() == 34 || now.minute() == 39 || now.minute() == 44 || now.minute() == 49 || now.minute() == 54 || now.minute() == 59) && now.second() < 10){
   dataFile = SD.open("datalogC.txt",FILE_READ);
   if(dataFile){
    while(dataFile.available()){
      float x = dataFile.parseFloat();
      nizHumidity[j] = x;
      j++;
      Serial.print("Member Humidity: ");
      Serial.print(j-1);
      Serial.print(" is: ");
      Serial.println(nizHumidity[j-1]);
      if(j==11){
        nizHumidity[j] = x;
        j = 0;
        midValueBoolH = true;
      }
    }
    dataFile.close();
        
   }
   else{
    Serial.println("error opening file");
   }
   delay(10000);
}


for(int i = 0; i<11; i++){  
  midValue += niz[i];
  midValueHumidity += nizHumidity[i];
}

    midValue = midValue/10;
    midValueHumidity = midValueHumidity/10;
  
  //writing everything on screen
  printLcdTemperature();
  printLcdHumidity();
  delay(2000);

  if(midValueBoolT == true && midValueBoolH == true){
  lcd.clear();
  printLcdMidTemperature(midValue);
  printLcdMidHumidity(midValueHumidity);
  delay(2000);
  }


}