#if defined(ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ESP32)
#include <WiFi.h>
#endif

//#include "ThingsBoard.h"
#include <PubSubClient.h>
#include "DHTesp.h"
#include <ESP32Servo.h>

#define CURRENT_FIRMWARE_TITLE    "TEST"
#define CURRENT_FIRMWARE_VERSION  "1.0.0"

const char *ssid = "Wokwi-GUEST";
const char *password = "";

// Baud rate for debug serial
#define SERIAL_DEBUG_BAUD   115200
const int DHT_PIN = 15;
const int POTENTIO_PIN = 36;
const int LDR_PIN = 39;
const int SERVO_PIN = 18;

const float GAMMA = 0.7;
const float RL10 = 50;

DHTesp dhtSensor;
Servo myServo;


// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
#define TOKEN             "AKJg5fiqv23itNmOTQVY" //Access token of device Display
const char* mqtt_server = "thingsboard.cloud";

// Initialize ThingsBoard client
WiFiClient wifiClient;
// Initialize ThingsBoard MQTT instance
//ThingsBoard tb(espClient);
PubSubClient client(wifiClient);
// the Wifi radio's status
int status = WL_IDLE_STATUS;

long randNumber;

void setup()
{
  Serial.begin(SERIAL_DEBUG_BAUD);
  delay(10);
  
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  pinMode(POTENTIO_PIN, INPUT);
  pinMode(LDR_PIN, INPUT);
  myServo.attach(SERVO_PIN,500,2400);
  

  Serial.print(" Connect to : ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
//  WiFi.config(IP, NETWORK, NETMASK, DNS);
  while (WiFi.status() != WL_CONNECTED)
{
  delay(500);
  Serial.print("...");
}
Serial.print("\n");
Serial.print("IP address : ");
Serial.print(WiFi.localIP());
Serial.print("\n");
Serial.print("Connect to : ");
Serial.println(ssid);    
client.setServer( mqtt_server, 1883);
// client.setCallback(callback);
}

void loop()
{
if ( !client.connected() ) 
{
    reconnect();
}
getData();
  delay(5000);
  //delay(300000);
}

void ServoRun(){
  int pos = 0;

  for(pos = 0; pos <= 180; pos++){
    myServo.write(pos);
    Serial.println(pos);
    delay(15);
  }
  for(pos = 180; pos >= 0; pos--){
    myServo.write(pos);
    Serial.println(pos);
    delay(15);
  }
}

void getData()
{
  TempAndHumidity  data = dhtSensor.getTempAndHumidity();

  int analogValue = analogRead(LDR_PIN);
  float voltage = analogValue / 4095. * 5;
  float resistance = 2000 * voltage / (1 - voltage / 5);
  float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));

  int PotensioValue=analogRead(POTENTIO_PIN);
  float voltagePotentio = PotensioValue*5/4095.0;
  float moisturePotensio = map(PotensioValue,0,4095,0,100);

  // Moisture <50%
  //Tulis kode untuk aktifkan servo jika moisture dibawah
  if (moisturePotensio > 50){
    ServoRun();
  }
  //Kode aktifkan Servo
  //ServoRun();

  // Kelembapan 50-60%
  // Suhu 20-35 
  // Lux 500-800

  

 


  /*for(pos = 0;pos <= 100; pos++){
    myServo.write(pos);
    Serial.print("posisi:  ");
    Serial.println(pos);
    delay(20);
  }

  for(pos = 100;pos >= 0; pos--){
    myServo.write(pos);
    Serial.print("posisi:  ");
    Serial.println(pos);
    delay(20);
  }*/


  Serial.print("Suhu : ");
  Serial.print(data.temperature); 
  Serial.print("Kelembaban : ");
  Serial.println(data.humidity);
  Serial.print("Moisture %: ");
  Serial.println(moisturePotensio);
  Serial.print("Lux: ");
  Serial.println(lux);


  /*
  String payload = "{";
  payload += "\"Suhu\":";
  payload += data.temperature;
  payload += ",";
  payload += "\"Kelembapan\":";
  payload += data.humidity;
  payload += ",";
  payload += "\"Potentio\":";
  payload += potentioint;
  payload += "}";

  char attributes[1000];
  payload.toCharArray( attributes, 1000 );
  client.publish( "v1/devices/me/telemetry",attributes);
  //client.publish( "v1/devices/me/attributes",attributes);
  Serial.println( attributes );   

  */
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    status = WiFi.status();
    if ( status != WL_CONNECTED) {
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("Connected to AP");
    }
    Serial.print("Connecting to ThingsBoard node ...");
    // Attempt to connect (clientId, username, password)
    if ( client.connect("e71d8f00-52ac-11ed-8ab1-ebe8b1422014", TOKEN, "") ) {
      Serial.println( "[DONE]" );
    } else {
      Serial.print( "[FAILED] [ rc = " );
      Serial.println( " : retrying in 5 seconds]" );
      delay( 500 );
    }
  }
}