首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么来自ESP32的这个POST请求控制KASA智能插头不能工作?

为什么来自ESP32的这个POST请求控制KASA智能插头不能工作?
EN

Stack Overflow用户
提问于 2022-07-03 07:32:00
回答 1查看 263关注 0票数 1

我试图使用通过HS103 (LoRa V2)发送的HTTPS POST请求与KASA的智能插头进行通信。对于实际的POST内容,我对HTTP非常陌生,并一直遵循以下说明:https://itnerd.space/2017/01/22/how-to-control-your-tp-link-hs100-smartplug-from-internet/

这是我试图发送的POST请求(修改了令牌和ID):

代码语言:javascript
运行
复制
URL: https://use1-wap.tplinkcloud.com/?token=fb2f7209-ATebDhHDOxB2wWc6wslPewO&appName=Kasa_Android&termID=1263f577-4387-4d3e-be79-705445d33bb08&appVer=1.4.4.607&ospf=Android+6.0.1&netType=wifi&locale=en_US

{
 "method":"passthrough",
 "params":{
 "deviceId":"80068FEB5A735A5BB187B4EC309EF1BE1D6D8997",
 "requestData":"{\"system\":{\"set_relay_state\":{\"state\":1}}}"
 }
}

这将打开智能插头。我已经通过在线API测试器(https://reqbin.com/)和我的MacBook上的cURL验证了POST请求本身是否有效。

我通过API测试器使用我的凭据(也在上面链接的说明中)使用我的凭据对token服务器进行身份验证,从而检索URL令牌和设备ID。

但是,当我用ESP32发送时,我无法控制智能插头。我正在使用Heltec框架/库通过Arduino IDE编写和编译。下面是我的代码(从Rui Santos 这里的代码开始,并为我的应用程序修改):

代码语言:javascript
运行
复制
/*
  Rui Santos
  Complete project details at Complete project details at https://RandomNerdTutorials.com/esp32-http-get-post-arduino/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

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

#include <WiFiClientSecure.h>


const char* ssid = "XXXXX";
const char* password = "XXXXX";

//Your Domain name with URL path or IP address with path
const char* serverName = "https://use1-wap.tplinkcloud.com/?token=fb2f7209-ATebDhHDOxB2wWc6wslPewO&appName=Kasa_Android&termID=1263f577-4387-4d3e-be79-705445d33bb08&appVer=1.4.4.607&ospf=Android+6.0.1&netType=wifi&locale=en_US HTTP/1.1";
const int port = 443;

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
// Timer set to 10 minutes (600000)
//unsigned long timerDelay = 600000;
// Set timer to 5 seconds (5000)
unsigned long timerDelay = 5000;

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}

void loop() {
  //Send an HTTP POST request every 10 minutes
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      WiFiClientSecure *client = new WiFiClientSecure;

      if (client) {
        Serial.println("Client Created!");
        //client -> setCACert(rootCACertificate);
        
        {
          HTTPClient http;
        
          // Your Domain name with URL path or IP address with path
          http.begin(*client, serverName);
          
          // If you need an HTTP request with a content type: application/json, use the following:
          http.addHeader("Content-Type", "application/json");
          //int httpResponseCode = http.POST("{\"api_key\":\"tPmAT5Ab3j7F9\",\"sensor\":\"BME280\",\"value1\":\"24.25\",\"value2\":\"49.54\",\"value3\":\"1005.14\"}");
          int httpResponseCode = http.POST("{\"method\":\"passthrough\", \"params\": {\"deviceId\": \"80068FEB5A735A5BB187B4EC309EF1BE1D6D8997\", \"requestData\": \"{\"system\":{\"set_relay_state\":{\"state\":0}}}\" }}");
         
          Serial.print("HTTP Response code: ");
          Serial.println(httpResponseCode);

          String payload = http.getString();
          Serial.print("HTTP String: ");
          Serial.println(payload);
            
          // Free resources
          http.end();
        }
        
        delete client;
      } else {
        Serial.println("Unable to create client");
      }
      
    } else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

以下是串行终端的输出:

代码语言:javascript
运行
复制
Connected to WiFi network with IP Address: 192.168.X.XXX
Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.
Client Created!
HTTP Response code: 200
HTTP String: {"error_code":-10100,"msg":"JSON format error"}

在ESP32上上传和运行时,智能插头不会关闭。

在网上快速搜索POST响应代码,接收200似乎意味着请求已处理完毕,但错误代码为负数,消息为"JSON格式错误“。

你知道为什么这个帖子请求不起作用吗?或者任何我应该试着获取更多信息的东西?

提前感谢!

EN

回答 1

Stack Overflow用户

发布于 2022-07-03 18:06:37

深入研究"JSON格式错误“--原来我在'requestData‘值周围有一个额外的"”,这个值在cURL中解析得很好,但是在通过ESP32发送raw时无法理解。

删除这些引号修复了问题,现在我能够成功地发送帖子请求。

下面是工作代码:

代码语言:javascript
运行
复制
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>

#include <Arduino_JSON.h>


const char* ssid = "XXXXX";
const char* password = "XXXXX";

//Your Domain name with URL path or IP address with path
const char* serverName = "https://use1-wap.tplinkcloud.com/?token=fb2f7209-ATebDhHDOxB2wWc6wslPewO&appName=Kasa_Android&termID=1163f577-4288-4d3d-be69-705445d33ba08&appVer=1.4.4.607&ospf=Android+6.0.1&netType=wifi&locale=en_US HTTP/1.1";

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
// Set timer to 5 seconds (5000)
unsigned long timerDelay = 5000;

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}

void loop() {
  //Send an HTTP POST request every 10 minutes
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      WiFiClientSecure *client = new WiFiClientSecure;

      if (client) {
        
        {
          HTTPClient http;
        
          // Your Domain name with URL path or IP address with path
          http.begin(*client, serverName);
          
          // If you need an HTTP request with a content type: application/json, use the following:
          http.addHeader("Content-Type", "application/json");
          int httpResponseCode = http.POST("{\"method\":\"passthrough\",\"params\":{\"deviceId\":\"80068FEB3A733B5BB287B4EC309FE1BE1D7D8997\",\"requestData\":{\"system\":{\"set_relay_state\":{\"state\":1}}}}}");
         
          Serial.print("HTTP Response code: ");
          Serial.println(httpResponseCode);

          String payload = http.getString();
          Serial.print("HTTP String: ");
          Serial.println(payload);
            
          // Free resources
          http.end();
        }
        
        delete client;
      } else {
        Serial.println("Unable to create client");
      }
      
    } else {
      Serial.println("WiFi Disconnected");
    }
    
    lastTime = millis();
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72844676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档