////Written by fourblackmans 10/6/2018

#include <RCSwitch.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>  


RCSwitch mySwitch = RCSwitch();// initialise RCswitch function to recieve signals from  the 433Mhz senders   
LiquidCrystal_I2C lcd(0x3f, 16, 2);  // set the LCD address to 0x27 or 0x3f for most 16x2 lcd's

const int ALARM = 7;  // used to have a LED on pin 7 to indicate sender triggered while alarm armed can also be used fora solenoid
const int LED = 8; //Alarm armed LED
const int ALARM2 = 9;   /// pin 9 can have soleniod connected to action siren if sender triggered while alarm armed

int ledState = LOW;  //Start in Disarmed state
int alarmState = LOW; // Start with alarm state as alarm not triggered

unsigned long previousMillis = 0; //for millis delay for length of time alarm sounds
const long interval = 120000; //length of time alarm sounds
unsigned long currentMillis = 0; //for millis delay for length of time alarm sounds

unsigned long previousMillis2 = 0;// for millis delay time serial print
const long interval2 = 1000;         // for millis delay time serial print

const byte speakerPin=5;  // Pin 5 for piezo buzzer
unsigned long lastPeriodStart;// For beeper
const int onDuration=500;// For beeper
const int periodDuration=700;// For beeper



void setup(){
  
  mySwitch.enableReceive(0);  //Myswitch waiting for 433mhz signals from senders
  pinMode(8, OUTPUT);// Alarm Armed indicator led
  pinMode(13, OUTPUT); //turn Arduinos onboard led on 13 off (because it is too bright at night:)
  pinMode(7, OUTPUT);  // Alarm triggered LED
  pinMode(9, OUTPUT); //Alarm triggered soloniod
  digitalWrite(LED, LOW);  //Start with armed LED off
  digitalWrite(ALARM, LOW);  //start with alarm LED off
  
  


  lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print(F("Alarm ON"));
  lcd.setCursor(0,1);
  lcd.print(F("Disarmed"));
   
//RTC section
Serial.begin(9600);
  // wait for Arduino Serial Monitor
  while (!Serial) ; 
  // get and set the time from the RTC
  setSyncProvider(RTC.get);   //get the time from RTC
  if (timeStatus() != timeSet) 
     Serial.println(F("Unable to sync with the RTC"));
  else
     Serial.println(F("RTC has set the system time"));     
   // to test your project, you can set the time manually 
   // setTime(22,14,55,1,1,11); // set time to 22:14 and 55 seconds on 1 Jan 2011

  // create  arm and disarm events  at specific times
  Alarm.alarmRepeat(6,00,0,MorningAlarm);  // DISARM time
  Alarm.alarmRepeat(22,15,0,EveningAlarm);  // ARM time

}


void loop(){

//RTC section
  {

  Alarm.delay(1); //Must be present for TimeAlrams to work
}

unsigned long currentMillis2 = millis();    //This section delays print time to serial to only once per second

  if (currentMillis2 - previousMillis2 >= interval2) {
    digitalClockDisplay();
    previousMillis2 = currentMillis2;
     }



  
if (alarmState == LOW)          //This section sounds buzzer without using delay command
{ lastPeriodStart = millis();}    
 if(alarmState == HIGH) //if sender is triggered the alarm state is set high and sounds the buzzer while alarm remains high (this is set for 120000 millis)
  {if (millis()-lastPeriodStart>=periodDuration)
  {lastPeriodStart+=periodDuration;
    tone(speakerPin, 1000, onDuration); // play 1000 Hz tone in background for 'onDuration'
 }
  }

if(alarmState == HIGH) {digitalWrite(ALARM2, HIGH);} //If alarm triggered make alrm solonoid pin (9) high

if(alarmState == LOW) {digitalWrite(ALARM2, LOW);}   //If alarm not triggered make alarm solonoid pin (9)low




if (mySwitch.getReceivedValue() == 1151636) //Fob arm button code
    {  ledState = HIGH;                  //if code is received set alarm state to armed
       digitalWrite(LED, HIGH);         // Turn on the alarm armed led
       tone(speakerPin, 1500);delay(100);noTone(speakerPin);delay(50); //Beep when Arming
       tone(speakerPin, 1500);delay(100);noTone(speakerPin);delay(50); 
       Serial.println(F("ON"));
       lcd.clear();
       lcd.setCursor(0,0); //Start at character 0 on line 0
       lcd.print(F("Alarm On"));
       lcd.setCursor(0,1);
       lcd.print(F("Armed")); }

       
    
if (mySwitch.getReceivedValue() == 1151634)  //Fob disarm button code
    { ledState = LOW;   //if code is received set alarm state to disarmed
      digitalWrite(LED, LOW);     //Turn off the alarm led
      Serial.println(F("OFF"));
      digitalWrite(ALARM, LOW);
      alarmState= LOW;
      tone(speakerPin,1500);delay(100);noTone(speakerPin);delay(50); //beep when disarming
      lcd.clear();
      lcd.setCursor(0,0); //Start at character 0 on line 0
      lcd.print(F("Alarm On"));
      lcd.setCursor(0,1);
      lcd.print(F("Disarmed")); }
 
 
    
if(ledState == HIGH && mySwitch.getReceivedValue() == 1151640)  // if the alarm is armed and this code is received do this
    {    
     digitalWrite(ALARM, HIGH);    //turn on the alarm solonoid pins
     alarmState = HIGH;            //Set the alarm state to alarm going off
     lcd.clear();
     lcd.setCursor(0,0); //Start at character 0 on line 0
     lcd.print(F("Alarm"));   //print message to lcd to know which sensor is was activated (and go and find the burglar :)
     lcd.setCursor(7, 0);  // PRINT hour to LCD
     if (hour() < 10)             
     lcd.print(F("0"));
     lcd.print(hour());
     lcd.setCursor(9, 0);
     lcd.print(F(":"));
     lcd.setCursor(10, 0);// PRINT minutes to LCD
     if (minute  () < 10)
     lcd.print(F("0"));
     lcd.print(minute());
     lcd.setCursor(0,1);
     lcd.print(F("Office cupboard")); //print message to lcd to know which sensor was activated (and go and find the burglar :)
 
  
  } 

  
  
if(ledState == HIGH && mySwitch.getReceivedValue() == 12345678) //Action for sender Office window
  {     // if the alarm is armed and the the 433mhz code above is received do this
     digitalWrite(ALARM, HIGH);    //turn on the alarm solonoid pins
     alarmState = HIGH;            //Set the alarm state to alarm going off
     lcd.clear();
     lcd.setCursor(0,0); //Start at character 0 on line 0
     lcd.print(F("Alarm"));   //print message to lcd to know which sensor was activated (and go and find the burglar :)
     lcd.setCursor(7, 0);  // PRINT hour to LCD
     if (hour() < 10)             
     lcd.print(F("0"));
     lcd.print(hour());
     lcd.setCursor(9, 0);
     lcd.print(F(":"));
     lcd.setCursor(10, 0);// PRINT minutes to LCD
     if (minute  () < 10)
     lcd.print(F("0"));
     lcd.print(minute());
     lcd.setCursor(0,1);
     lcd.print(F("sensornamehere"));  //print message to lcd to know which sensor is was activated (and go and find the burglar :)
 
  
  } 
  

 

  
    
unsigned long currentMillis = millis();   //This section allows the alarm state and alarm led to remain on for a set period
  if(alarmState == LOW) {previousMillis = millis();}

  if (currentMillis - previousMillis >= interval) {
     previousMillis = currentMillis;
    // if the alarm state and alarm led is on turn it off:
         alarmState = LOW;
      digitalWrite(ALARM, LOW);
   }

  mySwitch.resetAvailable(); 
     Alarm.delay(50);//for stability
  
}
///Section for functions

// functions to be called at certain times of day

// Disarm the alarm in the moring from RTC
void MorningAlarm() {
  // write here the task to perform every morning
  Serial.println(F("Disarmed"));
  digitalWrite(LED, LOW);  //turn the armed led off
  ledState = LOW;//  disarm the alarm
       lcd.clear();
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print(F("Alarm On"));
  lcd.setCursor(0,1);
  lcd.print(F("Disarmed"));
}
//Arm the alarm at night from RTC
void EveningAlarm() {
  // write here the task to perform every evening
  Serial.println(F("Armed"));
  digitalWrite(LED, HIGH);  //Turn the armed led on
  ledState = HIGH;   // arm the alarm
       lcd.clear();
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print(F("Alarm On"));
  lcd.setCursor(0,1);
  lcd.print(F("Armed"));
}
void digitalClockDisplay() {
  // digital clock display of the time on serial port
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}
void printDigits(int digits) {
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}
  ///RTC section end
