#include <WiFi.h>
#include <HTTPClient.h>
#include <PubSubClient.h>

String ip;
// WiFi 信息
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// MQTT 代理信息
const char* mqtt_server = "test.mosquitto.org";
const int mqtt_port = 1883;
char clientId[50];

// 訂閱的主題
const char* topic = "test/ledswitch706";
// WiFi 客戶端
WiFiClient espClient;
// MQTT 客戶端
PubSubClient client(espClient);
const int mqtt_ledPin = 15;
const int switch_ledPin = 4;

// WiFi 連線
void WiFi_connect(){
  Serial.println("Initializing WiFi...");
  WiFi.mode(WIFI_STA);
  WiFi.disconnect(); // 無線初始化
  Serial.println("Connecting to WiFi ");
  WiFi.begin("Wokwi-GUEST","");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.println("");
  Serial.println("WiFi connected");
  ip = WiFi.localIP().toString(); // 取得分配得到的 IP 位址
  Serial.println("IP address: " + ip);
  // 顯示 MAC 位址
  Serial.println("MAC address: "+ WiFi.macAddress());
}

// 當接收到訊息時的回調函數
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
  // 定義字符數組 buffer 陣列,長度為 length + 1
  char buffer[length + 1];
  // 將字節數組序列 payload 的內容複製到 buffer 中
  strncpy(buffer, (char*)payload, length);
  buffer[length] = '\0'; // 添加字符串結束符
  String message(buffer); // 將 buffer 轉換為字符串
  Serial.print("Received message: " + message); // 輸出接收到的消息
  Serial.println();
  String a = "switch";
  // 比較收到的訊息是否為 "switch"
  if (strcmp(message.c_str(),String("switch").c_str()) == 0) {
    // Serial.println("The two strings are equal.");
    // 讀取腳位狀態,回傳值為 HIGH 或 LOW
    int state = digitalRead(switch_ledPin); // HIGH or LOW
    if (state == 1) {
      digitalWrite(switch_ledPin, LOW);  // LED 關燈
    } else {
      digitalWrite(switch_ledPin, HIGH); // LED 開燈
    } 
  }
}

// MQTT 連線回調函數
void mqttReconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    long r = random(1000);
    sprintf(clientId, "clientId-%ld", r);
    if (client.connect(clientId)) {
      Serial.print(clientId);
      Serial.println(" connected");
      digitalWrite(mqtt_ledPin, HIGH);
    } else {
      digitalWrite(mqtt_ledPin, LOW);
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}
void setup() {
  Serial.begin(115200);
  randomSeed(analogRead((0)));
  int LED_BUILTIN = 2;
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(mqtt_ledPin, OUTPUT);
  pinMode(switch_ledPin, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  digitalWrite(mqtt_ledPin, LOW);
  digitalWrite(switch_ledPin, LOW);
  WiFi_connect();

  // 設置客戶端連線到的 MQTT 代理的服務器和端口
  client.setServer(mqtt_server, mqtt_port);
  // 設定當接收到 MQTT 訊息時執行的調函數
  client.setCallback(callback);
  // 判定 mqtt 連線是否成功 
  if (!client.connected()) {
    mqttReconnect(); // 執行 mqtt 連線是否成功
  }
  client.subscribe(topic); // 訂閱主題
}

void loop() {
  // mqtt 連線
  if (!client.connected()) {
    mqttReconnect(); // 執行 mqtt 重連調用函數
  }
  client.loop(); // 循環執行
  delay(5000); 
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
led1:A
led1:C
led2:A
led2:C