bblanchon / ArduinoJson

📟 JSON library for Arduino and embedded C++. Simple and efficient.
https://arduinojson.org
MIT License
6.73k stars 1.12k forks source link

HTTP POST not working for a JsonObject #877

Closed nakulbende closed 5 years ago

nakulbende commented 5 years ago

Making a esp8266 device on Blynk that can toggle/ control TP-link bulbs. The bulbs accept settings as a http POST with json object. Details are here. In the following code, if I just try to get json object printed, it formats perfectly and outputs on serial. But if I try to use the object with httpclient library, and submit a POST query, I get an error:

no matching function for call to 'HTTPClient::POST(ArduinoJson::JsonObject&)'

I am fairly new to both json and httpclient - if somebody can guide me it would be a great learning experience!

Thanks in advance!

Platform: esp8266
Compiler: Arduino IO 1.8.8
Libraries: ArduinoJson (5.13.4)

Code:

#include <ESP8266WiFi.h>        // Wifi library for ESP
#include <BlynkSimpleEsp8266.h> // Blynk library
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>

// Wifi, blynk credentials
const char* ssid     = "XXXX";                          // SSID
const char* password = "XXXXX";                // Password
char auth[] = "XXXX";        // Get token from Blynk

void setup()      
{
  // Serial port
  Serial.begin(74880);
  Serial.println("IFTTT tester");

  // Wifi connection and services
  startWiFi();                      // Connect to WIFI

  // Start configuration
  Blynk.config(auth);               // Connect to Blynk
  Blynk.connect();

  //JSON
  const size_t bufferSize = 2*JSON_OBJECT_SIZE(2);
  DynamicJsonBuffer jsonBuffer(bufferSize);

  JsonObject& desklamp = jsonBuffer.createObject();
  desklamp["method"] = "passthrough";

  JsonObject& params = desklamp.createNestedObject("params");
  params["deviceId"] = "123456789";
  params["requestData"] = "{\"smartlife.iot.smartbulb.lightingservice\":{\"transition_light_state\":{\"brightness\":20,\"on_off\":1,\"color_temp\":5000,\"transition_period\":2500}}}";

  desklamp.prettyPrintTo(Serial);

  // HTTP client
  HTTPClient http;
  http.begin("http://use1-wap.tplinkcloud.com/?token=TOKEN");
  http.addHeader("Content-Type", "application/json"); //Specify content-type header
  int httpCode = http.POST(desklamp); //Send the request
  String payload = http.getString(); //Get the response payload
  Serial.println(httpCode); //Print HTTP return code
  Serial.println(payload); //Print request response payload
  http.end(); //Close connection
}

void loop() {
 }

// Connect wifi
void startWiFi() { // Start a Wi-Fi access point, and try to connect to some given access points. Then wait for either an AP or STA connection
  WiFi.begin(ssid, password);                 // Connect to the network
  Serial.print("Connecting to ");             
  Serial.print(ssid); Serial.println(" ...");
  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {     // Wait for the Wi-Fi to connect
    delay(1000);
    Serial.print(++i); Serial.print(' ');
}
  }
  Serial.println('\n');
  Serial.println("Connection established!");  
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());             // Print IP address  
}

Compiler error:

C:\Users\Nakul Bende\Documents\Arduino\sketches\Sonoff_home_automation\sonoff_relay_switches_dht\ifttt_testing\ifttt_testing.ino: In function 'void setup()':

ifttt_testing:59:36: error: no matching function for call to 'HTTPClient::POST(ArduinoJson::JsonObject&)'

   int httpCode = http.POST(desklamp); //Send the request

                                    ^

C:\Users\Nakul Bende\Documents\Arduino\sketches\Sonoff_home_automation\sonoff_relay_switches_dht\ifttt_testing\ifttt_testing.ino:59:36: note: candidates are:

In file included from C:\Users\Nakul Bende\Documents\Arduino\sketches\Sonoff_home_automation\sonoff_relay_switches_dht\ifttt_testing\ifttt_testing.ino:4:0:

C:\Users\Nakul Bende\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:181:9: note: int HTTPClient::POST(uint8_t*, size_t)

     int POST(uint8_t * payload, size_t size);

         ^

C:\Users\Nakul Bende\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:181:9: note:   candidate expects 2 arguments, 1 provided

C:\Users\Nakul Bende\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:182:9: note: int HTTPClient::POST(String)

     int POST(String payload);

         ^

C:\Users\Nakul Bende\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:182:9: note:   no known conversion for argument 1 from 'ArduinoJson::JsonObject' to 'String'

Using library ESP8266WiFi at version 1.0 in folder: C:\Users\Nakul Bende\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266WiFi 
Using library Blynk at version 0.5.4 in folder: C:\Users\Nakul Bende\Documents\Arduino\libraries\Blynk 
Using library ArduinoJson at version 5.13.4 in folder: C:\Users\Nakul Bende\Documents\Arduino\libraries\ArduinoJson 
Using library ESP8266HTTPClient at version 1.2 in folder: C:\Users\Nakul Bende\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266HTTPClient 
exit status 1
no matching function for call to 'HTTPClient::POST(ArduinoJson::JsonObject&)'
bblanchon commented 5 years ago

Hi @nakulbende,

You need to serialize the JSON document to a string first:

String json;
desklamp.printTo(json);
int httpCode = http.POST(json);

I don't think there is an easy way to avoid the temporary string with this library.

Regards, Benoit

nakulbende commented 5 years ago

Works like a charm!

Thanks for the quick solution.

bblanchon commented 5 years ago

You're welcome! Thanks for using ArduinoJson.