#include <ESP8266WiFi.h> 
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <WiFiClientSecureBearSSL.h>                                                                                                                                                                                                                                   

const int servoPin = 0;
const uint8_t fingerprint[20] = {0xF9, 0xC2, 0x65, 0x6C, 0xF9, 0xEF, 0x7F, 0x66, 0x8B, 0xF7, 0x35, 0xFE, 0x15, 0xEA, 0x82, 0x9F, 0x5F, 0x55, 0x54, 0x3E};
int pos1 = 0; 
int pos2 =120;

void setup() {
    pinMode(LED_BUILTIN, OUTPUT); 
    pinMode(servoPin, OUTPUT); 
    Serial.begin(115200);
    WiFiManager wifiManager;
    //wifiManager.resetSettings();
    wifiManager.autoConnect("FishFeeder");
    if (WiFi.status()==WL_CONNECTED){
      fastblink(10,"Connection is Successful");
      }
      updateStatus();
      delay(5000);
}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) {
        if(getResult() == "1"){
          digitalWrite(LED_BUILTIN, LOW);
          Serial.println("Running Servo");
          runServo(servoPin,0);
          delay(2000);
          runServo(servoPin,180);
          delay(2000);
          runServo(servoPin,0);
          updateStatus();
          Serial.println("Stop Servo");
          delay(10000);
          digitalWrite(LED_BUILTIN, HIGH);
    }
    delay(10000);
  }
}

void fastblink(int count,String msg){
  for(int i=1;i<count;i++){
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH );
    delay(500);
  }
  Serial.println(msg);
}

String getResult(){
  String value ="";
  std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
  client->setFingerprint(fingerprint);
  HTTPClient https;
  if (https.begin(*client, "https://api.thingspeak.com/channels/665683/fields/2.json?api_key=QOIEGTM7XT0EKI0V&results=1")) {
      int httpCode = https.GET();
      if (httpCode > 0) {
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = https.getString();
          Serial.println(payload);
          const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(11) + 300;
          DynamicJsonBuffer jsonBuffer(capacity); 
          JsonObject& root = jsonBuffer.parseObject(https.getString());        
          JsonObject& feeds_0 = root["feeds"][0];
          const char* feeds_0_created_at = feeds_0["created_at"]; // "2019-05-27T14:57:36Z"
          int feeds_0_entry_id = feeds_0["entry_id"]; // 168
          const char* feeds_0_field2 = feeds_0["field2"]; // "0"
          Serial.println(feeds_0_field2);
          value = feeds_0_field2;
        } else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
      }
      https.end();
    } else {
      Serial.printf("[HTTP} Unable to connect\n");
    }
  }
  fastblink(2,"Got Response");
  return value;
}

void updateStatus(){
  std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
  client->setFingerprint(fingerprint);
  HTTPClient https;
  if (https.begin(*client, "https://api.thingspeak.com/update.json?api_key=8FC9LUB2AXVCZJ6L&field2=0")) {
      int httpCode = https.GET();
      if (httpCode > 0) {
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
        } else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
      }
      https.end();
    } else {
      Serial.printf("[HTTP} Unable to connect\n");
    }
  }
  fastblink(3,"Setting the field value to 0");
 }

 void runServo(int servoPin, int degree){
    int highDelay = 700;
    int lowDelay ; 
    int angle = (int)(5.55 * degree); 
    int Loop = 20000;   
    highDelay = highDelay + angle;
    lowDelay = Loop - highDelay -1000 ;
    for(int i=1;i<=15;i++){
        digitalWrite(servoPin, HIGH);
        delayMicroseconds(highDelay);
        digitalWrite(servoPin, LOW);
        delayMicroseconds(lowDelay);
        delay(1);
        }      
}
