/*
  Plant care with IOT
  The COVID-19 brought with it a new habit - house plants!
  Our project is meant to make house plant caring a lot more easy and efficient,
  with the combination of CPX, Integromat and Blynk you can do the following:
  1. The optimal temperature for house plants is 20-25 C. Using the CPX we constantly measure the temperature around the plants
     and if it is not optimal, the integromat app will send the user a notification saying the temperature is too cold or hot.
     Accordingly, the user can move the plant to a suitable location.
  2. Lighting is very importent for plants to grow. The light level is always displayed on the blynk app.
     This way, the user can ensure his plants are positioned in the best place in terms of lighting.
  3. Plants neeed water! Often people forget to water their plants and then they slowly die... therefore,
     if the users sets a watering sceduale on his google calendar, he can sync it with the CPX using the integromat so that each day on a given time,
     if it is a watering day - the CPX will announce it by playing a sound and blinking lights. The alarm will stop when the left button of the CPX is pressed.
  4. Each plant thrives in different humidity level. for example, plants that are originated in the tropical areas require high levels of humidity and cactuses
     require low levels of humidity. Using a weather web site, the CPX is updated once a day with the humidity level expected for this day.
     whenever the sideswitch on the CPX is one - the neopixsels will show the level of humidity by lighting as many neopixels in the following way:
     0-4% -> 0 neo-pixels
     5-14% -> 1 neo-pixel
     15-24% -> 2 neo-pixels
     ...
     95-100% -> 10 neo-pixels
*/ 
#include <cmath>
//Blynk related
#define BLYNK_PRINT SerialUSB
#define BLYNK_DEBUG SerialUSB
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <Adafruit_CircuitPlayground.h>
char auth[] = "XXXXXXXXXXX";  //Blynk AUTH TOKEN HERE
char ssid[] = "XXXXXXXXXXX";  //wifi network name here
char pass[] = "XXXXXXXXXXX";  //wifi password here
#define EspSerial Serial1
#define ESP8266_BAUD 9600
ESP8266 blynkWifi(&EspSerial);

int MINTEMP = 20;
int MAXTEMP = 25;
float currenttTemperature;
bool alarmIsOn = false;
double humidityLevel;
bool slideSwitch = CircuitPlayground.slideSwitch();
bool humidityModeIsOn = true;
int lightLevel;
int currentTempature;
bool flag = false;

void setup() {
  CircuitPlayground.begin();
  SerialUSB.begin(9600);
  EspSerial.begin(ESP8266_BAUD);
  delay(10);
  Blynk.begin(auth, blynkWifi, ssid, pass);
}

void loop() {
  delay(500);
  
  //show light level on Blynk app
  lightLevel = CircuitPlayground.lightSensor();
  Blynk.virtualWrite(V2, lightLevel);
  
  //check and notify if user needs to be updated about current tempature
  currenttTemperature = CircuitPlayground.temperature();
  if(currenttTemperature < MINTEMP){
    Serial.println("tap");
    notifyAllAboutTemp("cold");
  }else if(currenttTemperature > MAXTEMP){
    notifyAllAboutTemp("hot");
  }

  // show humidity level on CPX if required.
  slideSwitch = CircuitPlayground.slideSwitch();
  if(slideSwitch){
    Serial.println("on");
    turnOnHumidityMode();
  }else if(!slideSwitch && humidityModeIsOn){
    CircuitPlayground.clearPixels();
  }
}


void turnOnHumidityMode(){
  for(int i = 0; i < round(humidityLevel / 10); i++){
      CircuitPlayground.setPixelColor(i, 255,   51,   255);
   }
}

void notifyAllAboutTemp(String weather){
  String message;
  if(weather == "cold"){
    message = "The weather is currently too cold,\n please move the plant to a warmer place";
  }else{
    message = "The weather is currently too hot,\n please move the plant to a cooler place";
  }

  Blynk.virtualWrite(V3, message);
}

BLYNK_WRITE(V1) { //V1 is connected to a wathering scheduale via google calendar.
  alarmIsOn = true;
  CircuitPlayground.clearPixels();
  while(alarmIsOn){
    announceWateringDay();
    alarmIsOn = !CircuitPlayground.leftButton();  //when left button is pressed, turn off alarm
  }
}

BLYNK_WRITE(V0){  //V0 is connected to a weather website.
  humidityLevel = param.asDouble();
}

void announceWateringDay(){
  for(int i = 0; i < 10; i++){
      CircuitPlayground.setPixelColor(i, 0,   0,   255);
   }
   CircuitPlayground.playTone(263.63, 100);
   delay(1000);
   CircuitPlayground.clearPixels();
   delay(1000);
}
