<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      mqtt+esp32公網(wǎng)控制PIn 2 led燈

      PlatformIO 配置

      platformio.ini

      [env:esp32dev]
      platform = espressif32
      board = esp32dev
      framework = arduino
      monitor_speed = 115200
      lib_deps =knolleary/PubSubClient @ ^2.8
      build_flags =
        -D LED_PIN=2               ; 板載LED(可改成你的實(shí)際引腳)
        -D WIFI_SSID="你的WiFi"
        -D WIFI_PASS="你的WiFi密碼"
        -D MQTT_HOST="你的外網(wǎng)MQTT域名或IP"
        -D MQTT_PORT=1883          ; 先用1883,跑通后可換8883
        -D MQTT_USER="你的mqtt用戶名"
        -D MQTT_PASS="你的mqtt密碼"
        -D DEVICE_ID="esp32-led-01"
      

      main.cpp

      點(diǎn)擊查看代碼
      #include <WiFi.h>
      #include <PubSubClient.h>
      
      // ====== 編譯期注入的配置(見 platformio.ini)======
      #ifndef WIFI_SSID
      #define WIFI_SSID "YOUR_WIFI"
      #endif
      #ifndef WIFI_PASS
      #define WIFI_PASS "YOUR_PASS"
      #endif
      #ifndef MQTT_HOST
      #define MQTT_HOST "broker.example.com"
      #endif
      #ifndef MQTT_PORT
      #define MQTT_PORT 1883
      #endif
      #ifndef MQTT_USER
      #define MQTT_USER ""
      #endif
      #ifndef MQTT_PASS
      #define MQTT_PASS ""
      #endif
      #ifndef DEVICE_ID
      #define DEVICE_ID "esp32-led-01"
      #endif
      #ifndef LED_PIN
      #define LED_PIN 2
      #endif
      
      // ====== 主題約定 ======
      String t_base         = String("home/") + DEVICE_ID;
      String t_cmd          = t_base + "/cmd";
      String t_state        = t_base + "/state";
      String t_online       = t_base + "/online";  // LWT
      String t_ip           = t_base + "/ip";
      String t_rssi         = t_base + "/rssi";
      
      WiFiClient wifiClient;            // 先用非TLS,跑通后可改 WiFiClientSecure
      PubSubClient mqttClient(wifiClient);
      
      unsigned long lastReportMs = 0;
      bool ledOn = false;
      
      void setLed(bool on) {
        ledOn = on;
        digitalWrite(LED_PIN, on ? HIGH : LOW);
        // 上報(bào)狀態(tài)(retained),方便手機(jī)端看到最新狀態(tài)
        mqttClient.publish(t_state.c_str(), on ? "ON" : "OFF", true);
      }
      
      void ensureWiFi() {
        if (WiFi.status() == WL_CONNECTED) return;
        WiFi.mode(WIFI_STA);
        WiFi.begin(WIFI_SSID, WIFI_PASS);
        Serial.print("Connecting WiFi");
        int tries = 0;
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
          if (++tries > 60) { // 約30秒
            Serial.println("\nWiFi connect timeout, retry...");
            WiFi.disconnect(true);
            delay(1000);
            WiFi.begin(WIFI_SSID, WIFI_PASS);
            tries = 0;
          }
        }
        Serial.println("\nWiFi connected: " + WiFi.localIP().toString());
      }
      
      void mqttCallback(char* topic, byte* payload, unsigned int length) {
        String msg;
        msg.reserve(length);
        for (unsigned int i = 0; i < length; i++) msg += (char)payload[i];
        Serial.printf("MQTT <- [%s] %s\n", topic, msg.c_str());
      
        if (String(topic) == t_cmd) {
          // 兼容純文本與JSON
          String s = msg;
          s.toUpperCase();
          if (s == "ON") { setLed(true); return; }
          if (s == "OFF") { setLed(false); return; }
      
          // 簡(jiǎn)單JSON解析(不引lib,輕量處理)
          if (msg.indexOf("\"on\"")  != -1 || msg.indexOf("\"ON\"")  != -1) { setLed(true);  return; }
          if (msg.indexOf("\"off\"") != -1 || msg.indexOf("\"OFF\"") != -1) { setLed(false); return; }
        }
      }
      
      void ensureMQTT() {
        if (mqttClient.connected()) return;
      
        mqttClient.setServer(MQTT_HOST, MQTT_PORT);
        mqttClient.setCallback(mqttCallback);
      
        // LWT 設(shè)置:掉線時(shí) broker 自動(dòng)發(fā) "offline"
        // 注意:必須 connect() 時(shí)一次性傳入
        String clientId = String(DEVICE_ID) + "-" + String((uint32_t)ESP.getEfuseMac(), HEX);
        Serial.printf("Connecting MQTT as %s ...\n", clientId.c_str());
        if (mqttClient.connect(
              clientId.c_str(),
              MQTT_USER, MQTT_PASS,
              t_online.c_str(), 1, true, "offline"   // LWT: topic, qos, retained, payload
            )) {
          Serial.println("MQTT connected.");
          // 上線標(biāo)記
          mqttClient.publish(t_online.c_str(), "online", true);
          // 基礎(chǔ)信息(retained)
          mqttClient.publish(t_ip.c_str(), WiFi.localIP().toString().c_str(), true);
          // 訂閱控制主題
          mqttClient.subscribe(t_cmd.c_str());
          // 立即上報(bào)一次狀態(tài)(retained)
          setLed(ledOn);
        } else {
          Serial.printf("MQTT connect failed, state=%d\n", mqttClient.state());
        }
      }
      
      void setup() {
        Serial.begin(115200);
        pinMode(LED_PIN, OUTPUT);
        setLed(false);
      
        ensureWiFi();
        ensureMQTT();
      }
      
      void loop() {
        if (WiFi.status() != WL_CONNECTED) ensureWiFi();
        if (!mqttClient.connected()) ensureMQTT();
        mqttClient.loop();
      
        // 每10秒上報(bào)一次 RSSI,便于遠(yuǎn)程診斷
        unsigned long now = millis();
        if (now - lastReportMs > 10000 && mqttClient.connected()) {
          lastReportMs = now;
          long rssi = WiFi.RSSI();
          char buf[16];
          snprintf(buf, sizeof(buf), "%ld", rssi);
          mqttClient.publish(t_rssi.c_str(), buf, false);
        }
      }
      

      setup-mosquitto.sh

      點(diǎn)擊查看代碼
      #!/usr/bin/env bash
      set -euo pipefail
      
      # =========================
      # Mosquitto quick installer
      # - Creates MQTT user/password
      # - Configures 1883 and 8883 (TLS)
      # - Self-signed TLS by default, or Let's Encrypt with --letsencrypt
      # - Enables and starts systemd service
      # =========================
      
      USER_NAME=""
      USER_PASS=""
      DOMAIN=""
      EMAIL=""
      MODE="selfsigned" # or letsencrypt
      
      log() { echo -e "\033[1;32m[+] $*\033[0m"; }
      warn(){ echo -e "\033[1;33m[!] $*\033[0m"; }
      err() { echo -e "\033[1;31m[-] $*\033[0m" >&2; exit 1; }
      
      usage() {
        cat <<'EOF'
      Usage:
        setup-mosquitto.sh -u <user> -p <pass> -d <domain> [--selfsigned|--letsencrypt] [-m <email>]
      
      Examples:
        sudo ./setup-mosquitto.sh -u mqttuser -p mqttpass --selfsigned -d mqtt.example.com
        sudo ./setup-mosquitto.sh -u mqttuser -p mqttpass --letsencrypt -d mqtt.example.com -m you@example.com
      EOF
        exit 1
      }
      
      # ---- Parse args ----
      while [[ $# -gt 0 ]]; do
        case "$1" in
          -u) USER_NAME="${2:-}"; shift 2;;
          -p) USER_PASS="${2:-}"; shift 2;;
          -d) DOMAIN="${2:-}"; shift 2;;
          -m) EMAIL="${2:-}"; shift 2;;
          --selfsigned) MODE="selfsigned"; shift;;
          --letsencrypt) MODE="letsencrypt"; shift;;
          -h|--help) usage;;
          *) err "Unknown arg: $1";;
        esac
      done
      
      [[ -z "$USER_NAME" || -z "$USER_PASS" || -z "$DOMAIN" ]] && usage
      if [[ "$MODE" == "letsencrypt" && -z "$EMAIL" ]]; then
        err "Let's Encrypt mode requires -m <email>"
      fi
      
      # ---- OS detect ----
      if command -v apt-get >/dev/null 2>&1; then
        PKG_MGR="apt"
      elif command -v dnf >/dev/null 2>&1; then
        PKG_MGR="dnf"
      elif command -v yum >/dev/null 2>&1; then
        PKG_MGR="yum"
      else
        err "Unsupported OS: need apt, dnf or yum."
      fi
      log "Detected package manager: $PKG_MGR"
      
      # ---- Install packages ----
      log "Installing Mosquitto and tools..."
      if [[ "$PKG_MGR" == "apt" ]]; then
        apt-get update -y
        DEBIAN_FRONTEND=noninteractive apt-get install -y mosquitto mosquitto-clients openssl
        if [[ "$MODE" == "letsencrypt" ]]; then
          apt-get install -y certbot
        fi
      else
        # Enable EPEL on RHEL-like for mosquitto if needed
        if ! rpm -q mosquitto >/dev/null 2>&1; then
          if [[ "$PKG_MGR" != "apt" ]]; then
            if ! rpm -q epel-release >/dev/null 2>&1; then
              log "Installing EPEL repository..."
              if [[ "$PKG_MGR" == "dnf" ]]; then
                dnf install -y epel-release
              else
                yum install -y epel-release
              fi
            fi
          fi
        fi
        if [[ "$PKG_MGR" == "dnf" ]]; then
          dnf install -y mosquitto mosquitto-clients openssl
          [[ "$MODE" == "letsencrypt" ]] && dnf install -y certbot
        else
          yum install -y mosquitto mosquitto-clients openssl
          [[ "$MODE" == "letsencrypt" ]] && yum install -y certbot
        fi
      fi
      
      systemctl enable mosquitto >/dev/null 2>&1 || true
      
      # ---- Prepare directories ----
      CONF_DIR="/etc/mosquitto"
      CONF_D="${CONF_DIR}/conf.d"
      CERT_DIR="${CONF_DIR}/certs"
      PASS_FILE="${CONF_DIR}/passwd"
      mkdir -p "$CONF_D" "$CERT_DIR"
      
      # ---- Create MQTT user/password ----
      log "Creating MQTT user ..."
      # mosquitto_passwd will create file if not exist; -b for batch mode
      mosquitto_passwd -b -c "$PASS_FILE" "$USER_NAME" "$USER_PASS"
      chown mosquitto:mosquitto "$PASS_FILE"
      chmod 640 "$PASS_FILE"
      
      # ---- TLS certs ----
      CERT_FILE="${CERT_DIR}/server.crt"
      KEY_FILE="${CERT_DIR}/server.key"
      CHAIN_FILE="" # for LE
      
      if [[ "$MODE" == "selfsigned" ]]; then
        log "Generating self-signed certificate for CN=${DOMAIN} ..."
        openssl req -x509 -nodes -newkey rsa:2048 \
          -keyout "$KEY_FILE" \
          -out "$CERT_FILE" \
          -subj "/C=XX/ST=State/L=City/O=Org/OU=IT/CN=${DOMAIN}" \
          -days 825
        CHAIN_FILE="$CERT_FILE" # not used but keep var non-empty
      else
        log "Obtaining Let's Encrypt certificate for ${DOMAIN} (standalone) ..."
        # This will bind TCP/80 temporarily; ensure no web server occupies it.
        systemctl stop mosquitto || true
        certbot certonly --standalone --non-interactive --agree-tos \
          -m "$EMAIL" -d "$DOMAIN"
        CERT_FILE="/etc/letsencrypt/live/${DOMAIN}/fullchain.pem"
        KEY_FILE="/etc/letsencrypt/live/${DOMAIN}/privkey.pem"
        CHAIN_FILE="$CERT_FILE"
      fi
      
      chown -R mosquitto:mosquitto "$CERT_DIR" || true
      chmod 600 "$KEY_FILE" || true
      
      # ---- Write Mosquitto config ----
      SECURE_CONF="${CONF_D}/secure.conf"
      log "Writing Mosquitto config to ${SECURE_CONF} ..."
      cat > "$SECURE_CONF" <<EOF
      # ======= Generated by setup-mosquitto.sh =======
      persistence true
      persistence_location /var/lib/mosquitto/
      log_timestamp true
      log_type error
      log_type warning
      log_type notice
      log_type information
      
      # Global auth
      allow_anonymous false
      password_file ${PASS_FILE}
      
      # Plain MQTT (LAN / testing). Comment out to disable.
      listener 1883
      protocol mqtt
      
      # TLS listener for external access
      listener 8883
      protocol mqtt
      certfile ${CERT_FILE}
      keyfile ${KEY_FILE}
      
      # Optional: tune keepalive/limits (uncomment if needed)
      # max_inflight_messages 20
      # max_queued_messages 1000
      # autosave_interval 1800
      EOF
      
      # ---- Firewall rules ----
      if command -v ufw >/dev/null 2>&1; then
        if ufw status | grep -q "Status: active"; then
          log "Opening ports 1883 and 8883 in ufw ..."
          ufw allow 1883/tcp || true
          ufw allow 8883/tcp || true
        fi
      elif command -v firewall-cmd >/dev/null 2>&1; then
        if systemctl is-active --quiet firewalld; then
          log "Opening ports 1883 and 8883 in firewalld ..."
          firewall-cmd --add-port=1883/tcp --permanent || true
          firewall-cmd --add-port=8883/tcp --permanent || true
          firewall-cmd --reload || true
        fi
      else
        warn "No ufw/firewalld detected; ensure 1883/8883 are open in your security group."
      fi
      
      # ---- Restart service ----
      log "Restarting Mosquitto ..."
      systemctl restart mosquitto
      
      # ---- Show summary ----
      echo
      log "Done. Summary:"
      echo "  Broker (no TLS):  mqtt://${DOMAIN}:1883"
      echo "  Broker (TLS):     mqtts://${DOMAIN}:8883"
      echo "  User/Pass:        ${USER_NAME} / (hidden)"
      echo "  Password file:    ${PASS_FILE}"
      echo "  Config file:      ${SECURE_CONF}"
      if [[ "$MODE" == "selfsigned" ]]; then
        echo "  TLS (self-signed): ${CERT_FILE} / ${KEY_FILE}"
        warn "Clients must trust the self-signed cert (or disable cert validation for testing)."
      else
        echo "  TLS (LE):         ${CERT_FILE} / ${KEY_FILE}"
        warn "Certbot will NOT auto-reload mosquitto after renewal; consider a systemd timer hook."
      fi
      
      echo
      log "Quick test (without TLS):"
      echo "  # Publish:"
      echo "  mosquitto_pub -h ${DOMAIN} -p 1883 -u ${USER_NAME} -P '<pass>' -t test -m hello"
      echo "  # Subscribe:"
      echo "  mosquitto_sub -h ${DOMAIN} -p 1883 -u ${USER_NAME} -P '<pass>' -t test -v"
      echo
      log "Quick test (with TLS):"
      if [[ "$MODE" == "selfsigned" ]]; then
        echo "  mosquitto_sub -h ${DOMAIN} -p 8883 --capath /etc/ssl/certs -u ${USER_NAME} -P '<pass>' -t test -v --insecure"
        echo "  mosquitto_pub -h ${DOMAIN} -p 8883 --capath /etc/ssl/certs -u ${USER_NAME} -P '<pass>' -t test -m hello --insecure"
      else
        echo "  mosquitto_sub -h ${DOMAIN} -p 8883 --capath /etc/ssl/certs -u ${USER_NAME} -P '<pass>' -t test -v"
        echo "  mosquitto_pub -h ${DOMAIN} -p 8883 --capath /etc/ssl/certs -u ${USER_NAME} -P '<pass>' -t test -m hello"
      fi
      
      # Optional hint for LE auto-reload
      if [[ "$MODE" == "letsencrypt" ]]; then
        echo
        warn "Tip: add a certbot deploy hook to reload mosquitto after renewal:"
        echo '  echo -e "#!/bin/sh\nsystemctl reload mosquitto" | tee /etc/letsencrypt/renewal-hooks/deploy/mosquitto-reload.sh'
        echo '  chmod +x /etc/letsencrypt/renewal-hooks/deploy/mosquitto-reload.sh'
      fi
      
      chmod +x setup-mosquitto.sh
      sudo ./setup-mosquitto.sh -u mqttuser -p mqttpass --selfsigned -d mqtt.example.com
      # 或者用 Let’s Encrypt:
      # sudo ./setup-mosquitto.sh -u mqttuser -p mqttpass --letsencrypt -d mqtt.example.com -m you@example.com
      

      報(bào)錯(cuò)是:Duplicate persistence_location。
      說明全局項(xiàng) persistence / persistence_location 在兩個(gè)文件里都寫了(主文件 mosquitto.conf 和我們寫的 conf.d/secure.conf),Mosquitto 不允許重復(fù)定義。
      按下面修:

      0x01) 去掉 secure.conf 里的全局持久化兩行

      sudo sed -i 's/^\s*persistence\s\+.*/# &/' /etc/mosquitto/conf.d/secure.conf
      sudo sed -i 's/^\s*persistence_location\s\+.*/# &/' /etc/mosquitto/conf.d/secure.conf
      

      0x02)(可選保險(xiǎn))如果主配置里開了 port 1883,避免與 listener 1883 沖突

      sudo sed -i 's/^\s*port\s\+1883/# port 1883/' /etc/mosquitto/mosquitto.conf
      sudo sed -i 's/^\s*listener\s\+1883/# listener 1883/' /etc/mosquitto/mosquitto.conf
      sudo sed -i 's/^\s*listener\s\+8883/# listener 8883/' /etc/mosquitto/mosquitto.conf
      

      0x03) 重啟并看狀態(tài)

      sudo systemctl restart mosquitto
      sudo systemctl status mosquitto -l --no-pager
      

      0x04) 快速驗(yàn)證

      無 TLS
      mosquitto_sub -h <你的域名或IP> -p 1883 -u <user> -P '<pass>' -t test -v &
      mosquitto_pub  -h <你的域名或IP> -p 1883 -u <user> -P '<pass>' -t test -m hello
      

      電腦命令行測(cè)試(局域網(wǎng))

      訂閱狀態(tài)

      mosquitto_sub -h www.taotao01.fun -p 1883 -u mqttuser -P mqttpass -t home/esp32-led-01/state -v
      

      控制 LED

      # 開燈
      mosquitto_pub -h www.taotao01.fun -p 1883 -u mqttuser -P mqttpass -t home/esp32-led-01/cmd -m ON
      # 關(guān)燈
      mosquitto_pub -h www.taotao01.fun -p 1883 -u mqttuser -P mqttpass -t home/esp32-led-01/cmd -m OFF
      

      立刻停用 & 取消開機(jī)自啟

      sudo systemctl stop mosquitto
      sudo systemctl disable mosquitto
      sudo systemctl status mosquitto --no-pager
      
      關(guān)閉防火墻放行(按你系統(tǒng)其一執(zhí)行)
      
      UFW:
      
      sudo ufw delete allow 1883/tcp || true
      sudo ufw delete allow 8883/tcp || true
      
      firewalld:
      
      sudo firewall-cmd --remove-port=1883/tcp --permanent || true
      sudo firewall-cmd --remove-port=8883/tcp --permanent || true
      sudo firewall-cmd --reload || true
      
      停用配置(不刪,方便以后恢復(fù))
      
      sudo mv /etc/mosquitto/conf.d/secure.conf /etc/mosquitto/conf.d/secure.conf.disabled
      # 可選:清理賬號(hào)文件
      # sudo rm -f /etc/mosquitto/passwd
      
      檢查端口是否已關(guān)閉
      
      sudo ss -ltnp | grep -E ':(1883|8883)' || echo "1883/8883 已關(guān)閉"
      
      以后想再用
      
      sudo mv /etc/mosquitto/conf.d/secure.conf.disabled /etc/mosquitto/conf.d/secure.conf
      sudo systemctl enable mosquitto
      sudo systemctl start mosquitto
      
      想徹底卸載(可選)
      
      sudo apt-get purge -y mosquitto mosquitto-clients
      sudo rm -rf /etc/mosquitto /var/lib/mosquitto /var/log/mosquitto
      # 如果之前用了 Let's Encrypt,還可:
      # sudo certbot delete --cert-name www.taotao01.fun
      posted @ 2025-08-12 13:50  huh&uh  閱讀(22)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 久久久久香蕉国产线看观看伊| 国内精品久久人妻无码不卡| 中文有无人妻vs无码人妻激烈| 国产午夜福利免费入口| 中国CHINA体内裑精亚洲日本| 亚洲精品福利一区二区三区蜜桃| 日韩精品国产二区三区| 国产系列高清精品第一页| 国产日韩AV免费无码一区二区三区| 亚洲一区二区三区| 国产成人综合欧美精品久久| 亚洲精品久荜中文字幕 | 毛片亚洲AV无码精品国产午夜| 日韩高清亚洲日韩精品一区二区| 亚洲第一无码AV无码专区| 国产欧美日韩视频一区二区三区| 玩弄放荡人妻少妇系列| 国产精品久久久久久久专区| 国产真实伦在线观看视频| 北辰区| 国产精品黄色精品黄色大片| 五月开心六月丁香综合色啪| 国产偷国产偷亚洲高清日韩| 成在线人视频免费视频| 色综合 图片区 小说区| 国产精品自在线拍国产手机版| 色又黄又爽18禁免费视频| 五月国产综合视频在线观看| 色吊丝二区三区中文写幕| 精品尤物TV福利院在线网站| 国内自拍小视频在线看| 亚洲码和欧洲码一二三四| 人妻丰满熟妇av无码处处不卡| 欧美情侣性视频| 国产主播精品福利午夜二区| 日本中文字幕有码在线视频| 国产午夜亚洲精品不卡网站| 日韩中文字幕在线不卡一区| 国产成人精品无码专区| 九九久久人妻一区精品色| 成人免费乱码大片a毛片|