/***********************************************************************************************
 * Chickencoop door controller based on github project https://github.com/chrisuthe/CoopDoor   *
 * Dvere otvorené / zatvorené pri vypočítanom ZS / VS - Dusk2DawnDusk2Dawn library             *                                                                               *
 * Motor Driver TB6612 alebo použiť DRV8833                                                    *
 * A4 - SDA  RTC  DS3231                                                                       *
 * A5 - SCL  RTC  DS3231                                                                       *
 *                                                                                             *
 *                                                                                             *
 * - V1 - 25/07/2020                                                                           * 
 ***********************************************************************************************/


#include <math.h>
#include <Dusk2Dawn.h>
#include <EEPROM.h>
#include <Wire.h>
#include "RTClib.h"


// Define what pins are used
const int doorUpSensorPin   = A3;      // reedswitch door open
const int doorDownSensorPin = A2;      // reedswitch door close
const int EnableMotorPin    =  3;      // Enable motor
const int doorDownMotorPin  =  4;      // Smer motora down
const int DoorUpMotorPin    =  5;      // Smer motora up
const int builtInLED        =  6;      // LED signálizacia zatvor. dverí (reedswitch on pin A2)
const byte CloseDoorManual  =  7;      // Manuálne zatvorenie dverí

int buttonstateclose        =  0;
int currentMins;
int sunrise;                           // VS - východ slnka
int sunset;                            // ZS - západ slnka
    DateTime now;

  // Nastavujeme?
const bool debug  = true;
  // Do we need to set/adjust RTC?
const bool setRTC = false;   // setRTC = true, váš počítačový čas sa pri odovzdávaní náčrtu synchronizuje s časom RTC. 
                             // Po nahraní zmeňte setRTC = false a nahrajte sketch znovu.
  // Define RTC
     RTC_DS3231 rtc;         // Ak použijete iný RTC ako 3231 (napr. 1307), zmeňte tento riadok

  // Definujte miesto / časové pásmo pre dusk2dawn (toto je vaše mesto, 2-miestny kód krajiny)
  // Zmeňte svoje mesto a vyplňte súradnice a časové pásmo
     Dusk2Dawn Bratislava(49.03, 18.25, 1); // (použite google mapy, kliknite pravým tlačidlom myši „čo je tu“)

  // Funkcia nastavenia sa spustí raz, keď stlačíte reset alebo zapnete dosku
void setup() {
  
  // Defininácia režimov pinov
     pinMode(DoorUpMotorPin,   OUTPUT);
     pinMode(doorDownMotorPin, OUTPUT);
     pinMode(EnableMotorPin,   OUTPUT);
     pinMode(CloseDoorManual,   INPUT); 

  // Set Serial for Debugging
     if (debug) {
     Serial.begin(9600);

     if (!rtc.begin()) {
     Serial.println("Couldn't find RTC");
     while (1);
 }
    
     rtc.begin();
  // Umožňuje len nastaviť dátum a čas, keď je setRTC = true.
     if (setRTC)
 {
  // Zapíšte dátum a čas PC pri nahrávaní a keď je setRTC = true
     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

  // Odškrtnite riadok 73 na manuálne zapísanie dátumu a času do RTC, keď riadok 38 setRTC = true. Na testovanie ZS / VS
  // rtc.adjust(DateTime(2020, 8, 17, 12, 22, 20));       
 }
 }
  
  
  
  // Defininácia režimov pinov spínačov a signalizácie
     pinMode(doorUpSensorPin,   INPUT);
     pinMode(doorDownSensorPin, INPUT);
     pinMode(builtInLED,       OUTPUT);
    
     Serial.println("Dokončené nastavenie");
     if (digitalRead(doorUpSensorPin) == HIGH) 
 {
     Serial.println("Dvere sú otvorené");
 }

     if (digitalRead(doorDownSensorPin) == HIGH)
 {
     Serial.println("Dvere sú zatvorené");
 }
     delay(3000);
 }


  // Funkcia slučky beží až kým sa nevypne alebo nereštartuje
void loop() {
     delay(2000);
     if (debug){
     Serial.println();
     Serial.println("Hlavná slučka");
 }
  // Získajte dátum a čas z RTC
     now = rtc.now();
  // Získajte VS / ZS pre aktuálny rok / mesiac / deň ako hodnoty INT, ktoré sa rovnajú minútam od polnoci, kedy dôjde k VS, ZS. ( za letného času!)
     sunrise = Bratislava.sunrise(now.year(), now.month(), now.day(), true);
     sunset  = Bratislava.sunset (now.year(), now.month(), now.day(), true);
     if (debug) {
     Serial.println();
     Serial.print(now.year());
     Serial.print('/');
     Serial.print(now.month());
     Serial.print('/');
     Serial.print(now.day());
     Serial.print(" - ");
     Serial.print(now.hour());
     Serial.print(':');
     Serial.print(now.minute());
     Serial.print(':');
     Serial.print(now.second());
     Serial.print(':');
     Serial.print(sunrise+ 30);    // oneskorenie 30 minút
     Serial.print(sunset+ 30);     // oneskorenie 30 minút
 }

    
     buttonstateclose = digitalRead(CloseDoorManual);
     if(buttonstateclose == HIGH){
     ManualClose();
 }


  
  // Umožňuje pridať minúty a hodiny * 60 a zistiť, koľko minút sme od polnoci
     currentMins = ((now.hour()) * 60) + (now.minute());
     Serial.println(currentMins);
  // porovnávanie, ak majú byť dvere hore ...
  // oneskorenie 30 minút po západe slnka, pred zatvorením dverí. 
     if ((sunrise + 30 < currentMins && currentMins < sunset + 30) && ( buttonstateclose != HIGH))
 {
     Serial.println("Dvere by mali byť hore");
     while ( digitalRead(doorUpSensorPin) == LOW )
     raiseDoor();
 }

     else
 {
     Serial.println("Dvere by mali byť dole");
     while ( digitalRead(doorDownSensorPin) == LOW )
     lowerDoor();
 }

     int DoorUp   = digitalRead(doorUpSensorPin);
     int DoorDown = digitalRead(doorDownSensorPin);
/* This is just temporary switch debug code*/
     if (DoorUp == HIGH)
 {
     Serial.println("Dvere sa otvorili úplne");
     digitalWrite(builtInLED, LOW);
     stopDoor();
    
 }

     else
 {
     digitalRead(doorDownSensorPin == HIGH);
     Serial.println("Dvere sa zatvorili úplne");
     digitalWrite(builtInLED, HIGH);
     stopDoor();
    
 } 
 }



  // Posunte dvere hore
void raiseDoor() {
     digitalWrite(EnableMotorPin,  HIGH);
     digitalWrite(DoorUpMotorPin,  HIGH);
     digitalWrite(doorDownMotorPin, LOW);
     if (debug) {
     Serial.println("Posun dverí nahor");
 }
 }


  // Posunte dvere dolu
void lowerDoor() {
     digitalWrite(EnableMotorPin,   HIGH);
     digitalWrite(doorDownMotorPin, HIGH);
     digitalWrite(DoorUpMotorPin,    LOW);
     if (debug) {
     Serial.println("Posun dverí nadol");
 }
 }



  // Stop dvere
void stopDoor() {
     digitalWrite(EnableMotorPin,   LOW);
     digitalWrite(DoorUpMotorPin,   LOW);
     digitalWrite(doorDownMotorPin, LOW);
     if (debug) {
     Serial.println("Dvere Stop");
 }
 }


  // Zatvorte manuálne dvere
void ManualClose() { 
     digitalWrite(EnableMotorPin,   HIGH);
     digitalWrite(doorDownMotorPin, HIGH);
     digitalWrite(DoorUpMotorPin,    LOW);
     if (debug) {
     Serial.println("Manuálne dvere zatvorené");
     while ( digitalRead(doorDownSensorPin) == LOW)
     digitalWrite(builtInLED,       HIGH);
     stopDoor(); 
 }
 }
