#include "DFRobot_Iot.h"
#include "DFRobot_BC20.h"
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <DFRobot_NeoPixel.h>

#define RELAYPIN  D4
DFRobot_Iot myDevice;
DFRobot_BC20 myBC20;

/*Configure device certificate information*/
String ProductKey = "your_Product_Key";
String ClientId = "12345";/*Custom id*/
String DeviceName = "your_Device_Name";
String DeviceSecret = "your_Device_Secret";

/*Configure the domain name and port number*/
String ALIYUN_SERVER = "iot-as-mqtt.cn-shanghai.aliyuncs.com";
uint16_t PORT = 1883;

/*Product identifier that needs to be operated*/
String Identifier1 = "GeoLocation";
String Identifier2 = "LightSwitch";

/*TOPIC that need to be published and subscribed*/
const char * subTopic = "your_sub_Topic";//****set
const char * pubTopic = "your_pub_Topic";//******post

DFRobot_Iot myIot;
PubSubClient client;

static void closeRelay(){
  digitalWrite(RELAYPIN,LOW);
}

static void openRelay(){
  digitalWrite(RELAYPIN,HIGH);
}

void ConnectCloud() {
  while (!myBC20.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (myBC20.connect(myDevice._clientId, myDevice._username, myDevice._password)) {
      Serial.println("Connect Server OK");
      myBC20.SubTopic(0,1,subTopic,0);
    }
    else {
      myBC20.getQMTCONN();
      myBC20.SubTopic(0,1,subTopic,0);
    }
  }
}

void callback(char * topic, byte * payload, unsigned int len){
  Serial.print("Recevice [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < len; i++){
    Serial.print((char)payload[i]);
  }
  Serial.println();
  StaticJsonBuffer<300> jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject((const char *)payload);
  if(!root.success()){
    Serial.println("parseObject() failed");
    return;
  }
  const uint16_t relayState = root["params"][Identifier2];
  if(relayState == 0){
    closeRelay();
    Serial.println("close");
  }
  else if(relayState == 1){
    openRelay();
    Serial.println("open");
  }
  
  String tempMseg = "{\"id\":"+ClientId+",\"params\":{\""+Identifier2+"\":"+(String)relayState+"},\"method\":\"thing.event.property.post\"}";
  char sendMseg[tempMseg.length()];
  strcpy(sendMseg,tempMseg.c_str());
  client.publish(pubTopic,sendMseg);
}

void setup(){
  Serial.begin(115200);
  pinMode(RELAYPIN, OUTPUT);
  Serial.print("Starting the BC20.Please wait. . . ");
  while(!myBC20.powerOn()){
      delay(1000);
      Serial.print(".");
  }
  Serial.println("BC20 started successfully !");
  Serial.println("check OK");
  while (!myBC20.checkNBCard()) {
    Serial.println("Please insert the NB card !");
    delay(1000);
  }
  Serial.println("Waitting for access ...");
  while (myBC20.getGATT() == 0) {
    Serial.print(".");
    delay(1000);
  }
  if(myBC20.getQGNSSC() == OFF){
      Serial.println("open QGNSSC");
      myBC20.setQGNSSC(ON);
  }

  myDevice.init(ALIYUN_SERVER, ProductKey, ClientId, DeviceName, DeviceSecret);
  myBC20.setServer(myDevice._mqttServer, PORT);
  myBC20.setCallback(callback);
  ConnectCloud();
}

void loop(){
  if (!client.connected()) {
  ConnectCloud();
  }
  myBC20.getCLK();  // Get CLK from BC20
  myBC20.getQGNSSRD();
  myBC20.loop();
  myBC20.publish(pubTopic, ("{\"id\":"+ClientId+",\"params\":{\""+Identifier1+"\":{\"value\":{\"Longitude\":"+String(sGGNS.LongitudeVal,6)+",\"Latitude\":"+String(sGGNS.LatitudeVal,6)+",\"Altitude\":"+String(sGGNS.Altitude,6)+",\"CoordinateSystem\":"+(String)2+"}}},\"method\":\"thing.event.property.post\"  }"));
  Serial.println("Data is published to cloud.");
  delay(20000);
}
