#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <WebSocketsClient.h>

char ssid[] = "你的WIFI名"; 
char pswd[] = "wifi密码";


DynamicJsonDocument jsonBuffer(100);
JsonObject jsonStr;
WiFiMulti WiFiMulti;
WebSocketsClient webSocket;

#define D1 32
#define D2 33
#define D3 25
#define D4 26
#define D5 27
#define D6 14
#define D7 12
#define D8 13
#define D9 15
#define D10 2
bool bl1 = false;
bool bl2 = false;
bool bl3 = false;
bool bl4 = false;
bool bl5 = false;
bool bl6 = false;
bool bl7 = false;
bool bl8 = false;
bool bl9 = false;
bool bl10 = false;
void hexdump(const void* mem, uint32_t len, uint8_t cols = 16) {
  const uint8_t* src = (const uint8_t*)mem;
  Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
  for (uint32_t i = 0; i < len; i++) {
    if (i % cols == 0) {
      Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
    }
    Serial.printf("%02X ", *src);
    src++;
  }
  Serial.printf("\n");
}

void webSocketEvent(WStype_t type, uint8_t* payload, size_t length) {

  switch (type) {
    case WStype_DISCONNECTED:
      Serial.printf("[WSc] Disconnected!\n");
      break;
    case WStype_CONNECTED:
      Serial.printf("[WSc] Connected to url: %s\n", payload);

      // send message to server when Connected
      webSocket.sendTXT("Connected");
      break;
    case WStype_TEXT:
      Serial.printf("[WSc] get text: %s\n", payload);

      deserializeJson(jsonBuffer, payload);
      jsonStr = jsonBuffer.as<JsonObject>();
      if (jsonStr["message"] != "") {

        if (jsonStr["message"] == "bt01") {
          if (bl1 == false) {
            bl1 = true;
            bl2 = false;
            //digitalWrite(D2, LOW);
            //webSocket.sendTXT("已停");
            webSocket.sendTXT("bt01on");
          } else {
            bl1 = false;
            webSocket.sendTXT("bt01off");
          }
        }
        if (jsonStr["message"] == "bt02") {
          if (bl2 == false) {
            bl2 = true;
            bl1 = false;
            // digitalWrite(D1, LOW);
            webSocket.sendTXT("bt02on");
          } else {
            bl2 = false;
            webSocket.sendTXT("bt02off");
          }
        }
        if (jsonStr["message"] == "bt03") {
          if (bl3 == false) {
            bl3 = true;
            digitalWrite(D3, HIGH);
            webSocket.sendTXT("bt03on");
          } else {
            bl3 = false;
            digitalWrite(D3, LOW);
            webSocket.sendTXT("bt03off");
          }
        }
        if (jsonStr["message"] == "bt04") {
          if (bl4 == false) {
            bl4 = true;
            digitalWrite(D4, HIGH);
            webSocket.sendTXT("bt04on");
          } else {
            bl4 = false;
            digitalWrite(D4, LOW);
            webSocket.sendTXT("bt04off");
          }
        }
        if (jsonStr["message"] == "bt05") {
          if (bl5 == false) {
            bl5 = true;
            digitalWrite(D5, HIGH);
            webSocket.sendTXT("bt05on");
          } else {
            bl4 = false;
            digitalWrite(D4, LOW);
            webSocket.sendTXT("bt05off");
          }
        }
        if (jsonStr["message"] == "bt06") {
          if (bl6 == false) {
            bl6 = true;
            digitalWrite(D6, HIGH);
            webSocket.sendTXT("bt06on");
          } else {
            bl6 = false;
            digitalWrite(D6, LOW);
            webSocket.sendTXT("bt06off");
          }
        }
        if (jsonStr["message"] == "bt07") {
          if (bl7 == false) {
            bl7 = true;
            digitalWrite(D7, HIGH);
            webSocket.sendTXT("bt07on");
          } else {
            bl7 = false;
            digitalWrite(D7, LOW);
            webSocket.sendTXT("bt07off");
          }
        }
        if (jsonStr["message"] == "bt08") {
          if (bl8 == false) {
            bl8 = true;
            digitalWrite(D8, HIGH);
            webSocket.sendTXT("bt08on");
          } else {
            bl4 = false;
            digitalWrite(D8, LOW);
            webSocket.sendTXT("bt08off");
          }
        }
        if (jsonStr["message"] == "bt09") {
          if (bl9 == false) {
            bl9 = true;
            digitalWrite(D9, HIGH);
            webSocket.sendTXT("bt09on");
          } else {
            bl4 = false;
            digitalWrite(D9, LOW);
             webSocket.sendTXT("bt09off");
          }
        }

        if (jsonStr["message"] == "bt10") {
          if (bl10 == false) {
            bl10 = true;
            webSocket.sendTXT("bt10on");
          } else {
            bl10 = false;
            webSocket.sendTXT("bt10off");
          }
        }
      }
      // send message to server
      // webSocket.sendTXT("message here");
      break;
    case WStype_BIN:
      Serial.printf("[WSc] get binary length: %u\n", length);
      hexdump(payload, length);

      // send data to server
      // webSocket.sendBIN(payload, length);
      break;
    case WStype_ERROR:
    case WStype_FRAGMENT_TEXT_START:
    case WStype_FRAGMENT_BIN_START:
    case WStype_FRAGMENT:
    case WStype_FRAGMENT_FIN:
      break;
  }
}

void setup() {
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);
  pinMode(D4, OUTPUT);
  pinMode(D5, OUTPUT);
  pinMode(D6, OUTPUT);
  pinMode(D7, OUTPUT);
  pinMode(D8, OUTPUT);
  pinMode(D9, OUTPUT);
  pinMode(D10, OUTPUT);
  digitalWrite(D1, LOW);
  digitalWrite(D2, LOW);
  digitalWrite(D3, LOW);
  digitalWrite(D4, LOW);
  digitalWrite(D5, LOW);
  digitalWrite(D6, LOW);
  digitalWrite(D7, LOW);
  digitalWrite(D8, LOW);
  digitalWrite(D9, LOW);
  digitalWrite(D10, LOW);
  Serial.begin(115200);

  //Serial.setDebugOutput(true);
  for (uint8_t t = 2; t > 0; t--) {
    Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFiMulti.addAP(ssid, pswd);

  //WiFi.disconnect();
  while (WiFiMulti.run() != WL_CONNECTED) {
    delay(100);
  }
  Serial.println("连网成功");
  // server address, port and URL 114.132.96.86
  webSocket.begin("114.132.96.86", 80, "/ws/ws-login");
  webSocket.setAuthorization("user=nodeMCUesp32&passwd=abcdefg&room=esp");
  // event handler
  webSocket.onEvent(webSocketEvent);
  // try ever 5000 again if connection has failed
  webSocket.setReconnectInterval(5000);
}

void loop() {
  webSocket.loop();

  if (bl1 == true && bl10 == true) {
    digitalWrite(D2, LOW);
    digitalWrite(D1, HIGH);
    digitalWrite(D10, HIGH);
    delay(1000);
    digitalWrite(D1, LOW);
    digitalWrite(D10, LOW);
  } else if (bl2 == true && bl10 == true) {
    digitalWrite(D1, LOW);
    digitalWrite(D2, HIGH);
    digitalWrite(D10, HIGH);
    delay(1000);
    digitalWrite(D2, LOW);
    digitalWrite(D10, LOW);
  } else {
    if (bl1 == true) {
      digitalWrite(D2, LOW);
      digitalWrite(D1, HIGH);
      delay(1000);
      digitalWrite(D1, LOW);
    }
    if (bl2 == true) {
      digitalWrite(D1, LOW);
      digitalWrite(D2, HIGH);
      delay(1000);
      digitalWrite(D2, LOW);
    }
    if (bl10 == true) {
      digitalWrite(D10, HIGH);
      delay(1000);
      digitalWrite(D10, LOW);
    }
  }
}
