#include <Arduino.h>

// MQTT服务器配置
const char* mqttServer = "wulian.nobiggie.cn";
const int mqttPort = 1883;
const char* clientId = "alarm-101";
const char* username = "alarm-101";
const char* password = "abcdefg";
const char* sutopic = "water/alarm-101/control";
const char* putopic = "water/alarm-101/data";

// 定义引脚数组 分别代表水位 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
const int pins[] = {39, 34, 35, 32, 33, 25, 26, 27, 14 ,13};
const int numPins = sizeof(pins) / sizeof(pins[0]);
// 缓冲区和超时设置
char response[256];
unsigned long timeout;
int waterV = 0;
bool mqttConnet = false;
int i = 10;
String connectCmd = "";


String inputString = "";  // 用于存储接收到的数据
bool breakbl = false;
void setup() {
  // 初始化串口通信
  Serial.begin(115200);
  // 设置水位检测引脚为输入模式
  for (int i = 0; i < numPins; i++) {
    pinMode(pins[i], INPUT);
    delay(200);
  }

  Serial.println("开始启动GSM");
  delay(28000);  //等待GSM启动完成
  // 连接MQTT服务器
  connectCmd = "AT+CMQTTCONNECT=0,\"tcp://";
  connectCmd += mqttServer;
  connectCmd += ":";
  connectCmd += String(mqttPort);
  connectCmd += "\",60,1,\"";
  connectCmd += username;
  connectCmd += "\",\"";
  connectCmd += password;
  connectCmd += "\"";
  Serial.println("AT+CMQTTCFG=\"argtopic\",0,1,1");
  delay(500);
}
bool mConnet() {

  // 启动MQTT
  if (sendATCommand("AT+CMQTTSTART", "OK", 5000)) {
    // 设置MQTT账户
    if (sendATCommand("AT+CMQTTACCQ=0,\"A7670C\"", "OK", 5000)) {
      //Serial.println("MQTT account set successfully");
      if (sendATCommand(connectCmd.c_str(), "OK", 10000)) {
        return true;
        Serial.println("Connected to MQTT server");
        int topicLen = String(sutopic).length();
        String subFrameCmd = "AT+CMQTTSUB=0," + String(topicLen) + ",0";
        //订阅主题
        if (sendATCommand(subFrameCmd.c_str(), ">", 2000)) {
          if (sendATCommand(sutopic, "OK", 2000)) {
            return true;
            //     //Serial.println("Subscribed to topic successfully");
            //     const char* a = "10";
            //     publishMQTTMessage(putopic, a);
            //   } else {
            //     Serial.println("Failed to send topic");
          }
          return false;
        } else {
          Serial.println("Failed to start subscription");
          return false;
        }
      } else {

        Serial.println("Failed to connect to MQTT server");
        return false;
      }
    } else {
      Serial.println("Failed to set MQTT account");
      return false;
    }
  } else {
    Serial.println("Failed to start MQTT");
    return false;
  }
}
void loop() {
  // 设置水位检测引脚为输入模式
  for (int i = 0; i < numPins; i++) {
    if (digitalRead(pins[i]) == HIGH) {
      waterV = (i + 1) * 10;
    }
  }
  if (mqttConnet) {
    //i++;
    String tmp = String(waterV);
    waterV = 0;
    publishMQTTMessage(putopic, tmp.c_str());
  } else {
    mqttConnet = mConnet();
  }

  // 可以在这里添加发布消息的代码
  delay(20000);
}

bool sendATCommand(const char* command, const char* expectedResponse, unsigned long timeout) {
  if (command != "AT") {
    Serial.println(command);
  } else {
    Serial.print("[发送指令] ");
    Serial.println(command);
  }


  // 清空接收缓冲区
  while (Serial.available()) {
    Serial.read();
  }

  String response = "";
  unsigned long startTime = millis();

  while (millis() - startTime < timeout) {
    // 读取所有可用数据
    while (Serial.available()) {
      char c = Serial.read();
      response += c;
      delay(1);  // 防止数据丢失
    }

    // 检查是否包含预期响应（忽略大小写）
    if (response.indexOf(expectedResponse) != -1) {
      String bb = String(command);
      if (bb.indexOf("AT+CMQTTPAYLOAD=") != -1 || bb.indexOf("AT+") == -1) {
        return true;
      }
      //Serial.print("[指令成功] ");
      return true;
    }

    // 检查是否包含错误
    if (response.indexOf("ERROR") != -1) {
      Serial.print("[指令失败] ");
      return false;
    }

    delay(10);  // 避免CPU占用过高
  }

  Serial.print("[指令超时] ");
  return false;
}

bool publishMQTTMessage(const char* putopic, const char* payload) {
  int topicLength = strlen(putopic);
  int payloadLength = strlen(payload);

  // 设置主题长度
  String topicLenCmd = "AT+CMQTTTOPIC=0," + String(topicLength);
  if (!sendATCommand(topicLenCmd.c_str(), ">", 5000)) {
    Serial.print("[发布主题长度失败] ");
    return false;
  }

  // 发送主题内容
  //Serial.print("[发送主题] ");
  Serial.println(putopic);
  delay(500);
  // 设置负载长度
  String payloadLenCmd = "AT+CMQTTPAYLOAD=0," + String(payloadLength);
  if (!sendATCommand(payloadLenCmd.c_str(), ">", 5000)) {
    return false;
  }

  // 发送负载内容

  if (!sendATCommand(payload, "OK", 1000)) {
    return false;
  }


  String aa = "AT+CMQTTPUB=0,0," + String(payloadLength);
  // 发布消息 (QoS=0, 保留=0)
  if (!sendATCommand(aa.c_str(), "+CMQTTPUB: 0,0", 8000)) {
    return false;
  }


  return true;
}
