// This example uses an Arduino/Genuino Zero together with
// by Gilberto Conti
// https://github.com/256dpi/arduino-mqtt

#include <ESP8266WiFi.h>
#include <MQTT.h>
#include <ArduinoJson.h>

const char ssid[] = "yckj01";
const char pass[] = "yckj2015";

const char clientId[] = "client1";
const char username[] = "user1";
const char password[] = "123456";

WiFiClient net;
MQTTClient client;
unsigned long heartLong = 30; //
unsigned long lastMillis = 0;
void serialRead()
{
  String inputString = "";
  while (Serial.available())
  {
    inputString = inputString + char(Serial.read());
    delay(2);
  }
  if (inputString.length() > 0)
  {
    Serial.println("inputString:" + inputString); //把字符串传给串口
  }
}

void connect()
{
  Serial.print("checking wifi...");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(1000);
  }

  Serial.print("\nconnecting...");
  while (!client.connect(clientId, username, password))
  {
    Serial.print(".");
    delay(1000);
  }

  Serial.println("\nconnected!");

  client.subscribe("/allot/request");
  // client.unsubscribe("/hello");
}

void messageReceived(String &topic, String &payload)
{
  Serial.println("incoming: " + topic + " - " + payload);
  DynamicJsonDocument doc(1024);
  deserializeJson(doc, payload);
  JsonObject obj = doc.as<JsonObject>();
  String name = obj["name"];
  Serial.println("json:name: " + name);
  // Note: Do not use the client in the callback to publish, subscribe or
  // unsubscribe as it may cause deadlocks when other things arrive while
  // sending and receiving acknowledgments. Instead, change a global variable,
  // or push to a queue and handle it in the loop after calling `client.loop()`.
}

void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, pass);

  // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported
  // by Arduino. You need to set the IP address directly.
  //
  // MQTT brokers usually use port 8883 for secure connections.
  client.begin("qqyun.itbbn.top", 1883, net);
  client.onMessage(messageReceived);
  client.setKeepAlive(heartLong); //设置心跳时长
  connect();
}

void loop()
{
  client.loop();

  if (!client.connected())
  {
    connect();
  }

  // publish a message roughly every second.
  unsigned long heartLongL = heartLong * 1000;
  if (millis() - lastMillis > heartLongL)
  {
    lastMillis = millis();
    String heartInfo = "{\"name\":\"nodencu1\",\"time\":\"" + String(lastMillis) + "\"}";
    client.publish("/allot/heart", heartInfo);
  }
  serialRead();
}