Closed lcfelippe closed 4 years ago
bblancon, Thank you for your reply...
I have already tried this examples, but in this case the server send json data to a client. I need that the client read all the sensors and send json to a server. Maybe it's easy to do, but I'm newbie on http protocols.
Can you help me, how to make this?
Regards,
lcfelippe.
Thank you for your patience.
I have no doubts about how to serialize or deserialize the json. My only problem is how to send it from client to server.
Regards,
lcfelippe.
@lcfelippe, the serialization tutorial shows how to POST the data to a Web service. What else do you need?
@bblanchon, i need to know how can i prepare the server to receive the Json data. My project is a Weather Station that collect data and send it to wunderground. Now, i would like to serialize this data and send it to a Esp8266 (server) to display the weather information on ILI9341TFT Display.
Below a example of my serialized data:
{"Weather":"Sensors","Date":{"Day":165,"Month":165,"Year":2165,"Weekday":"Monday"},"Time":{"Hour":165,"Minute":165,"Second":85},"WiFi":{"WiFi Signal Strenght":45},"BME280":{"Temperature":0,"Humidity":0,"DewPoint":0,"Pressure":0,"Pressure Equivalent":0},"VEML-6075":{"UVA":0,"UVB":0,"UV Index":0},"PMS 5003":{"Last Read Sample":{"PM 1.0":0,"PM 2.5":0,"PM 10":0},"Total of 24hs PM 2.5":0,"Average of 24hs PM 2.5":0,"PM 2.5 AQI":0,"Air Quality PM 2.5":"","Total of 24hs PM 10":0,"Average of 24hs PM 10":0,"PM 10 AQI":0,"Air Quality PM 10":"","Air Quality Comparison":""},"Rain Bucket":{"Rain Rate":0,"Rain Total":0},"Wind":{"Speed":0,"Direction Cardinal":"","Direction Degrees":0},"Circuit Temperature":{"Circuit":0,"Battery 1":0,"Battery 2":0}}
Hi @lcfelippe,
I don't have a ready-made example of an HTTP server that deserializes a JSON document from the request body. However, you can easily build from the two following examples:
Combining the two programs should be fairly easy.
Best regards, Benoit
Hi @bblanchon,
I don't have good skills with HTTP protocols, therefore the examples didn't help me to solve my necessity. I'll try to manage the data between the Esp8266 using a 433Mhz transmitter and send a structure instead of the Json data.
struct sensor { float temp; float pressure; float humidity; };
Thank you for the help. 👍
@lcfelippe, As your client will submit the data to your server you need to use HTTP POST (or PUT) requests from the client side, rather than GET commands. You can follow these examples:
First, you need to settle on an URI where the client will post the JSON data and the server will accept it e.g. "_/rest/postdata"
Then on the client code change the line accordingly to the chosen URI
http.begin(client, "http://"<SERVER_IP>"/postplain/"); //HTTP
to
http.begin(client, "http://<SERVER_IP>/rest/post_data"); //HTTP
Change
On the client side, also change the line of code
int httpCode = http.POST("{\"hello\":\"world\"}");
to your serialized json. You can build your JSON data by simple string concatenation of keys and values.
On the server side, change these lines of code:
server.on("/inline", []() {
server.send(200, "text/plain", "this works as well");
});
to
server.on("/rest/post_data", []() {
if (server.hasArg("plain")== false){ //Check if body received
server.send(400, "text/plain", "Bad request: body not received");
} else { // we received a body, hopefully our JSON data
String message = server.arg("plain");
message += "\n";
// Allocate the JSON document
// Use arduinojson.org/v6/assistant to compute the capacity.
const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
DynamicJsonDocument doc(capacity);
// Parse JSON object
DeserializationError error = deserializeJson(doc, message);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
// incorporate the parsing of your JSON data as per the [JsonHttpClient.ino](https://arduinojson.org/v6/example/http-client/) example
}
}
Get rid of other server.on() pieces of code, unless you want to extend your web server to serve more requests...
There is a good tutorial here
Good luck... Ewald
Hi @ewaldc, Thank you for the examples, and for the instructions to modify the code.
The only issue is that the Client only send the Json data to a server once. To send it again i have to reboot the client.
After read all sensors i have the code below on void loop
buffer was declared as global variable (String).
Code:
void loop(){
.
.
.
DynamicJsonDocument weather(2048);
weather["Weather"]= "Sensors";
weather["Date"]["Day"] = now.day();
weather["Date"]["Month"] = now.month();
weather["Date"]["Year"] = now.year();
weather["Date"]["Weekday"] = daysOfTheWeek[now.dayOfTheWeek()];
weather["Time"]["Hour"] = now.hour();
weather["Time"]["Minute"] = now.minute();
weather["Time"]["Second"] = now.second();
weather["WiFi"]["WiFi Signal Strenght"] = Signal_Strength;
weather["BME280"]["Temperature"] = tempc;
weather["BME280"]["Humidity"] = humidity;
weather["BME280"]["DewPoint"] = dewpointc;
weather["BME280"]["Pressure"] = pressure;
weather["BME280"]["Pressure Equivalent"] = slpressure_mB;
weather["BME280"]["Heat Index"] = Heat_Index;
weather["VEML-6075"]["UVA"] = uvia;
weather["VEML-6075"]["UVB"] = uvib;
weather["VEML-6075"]["UV Index"] = uvi;
weather["PMS 5003"]["Last Read Sample"]["PM 1.0"] = PM_1wu;
weather["PMS 5003"]["Last Read Sample"]["PM 2.5"] = PM_2_5wu;
weather["PMS 5003"]["Last Read Sample"]["PM 10"] = PM_10wu;
weather["PMS 5003"]["Total of 24hs PM 2.5"] = total24hs_PM_2_5;
weather["PMS 5003"]["Average of 24hs PM 2.5"] = media24hs_PM_2_5;
weather["PMS 5003"]["PM 2.5 AQI"] = AQI_PM_2_5;
weather["PMS 5003"]["Air Quality PM 2.5"] = air_quality_PM_2_5;
weather["PMS 5003"]["Total of 24hs PM 10"] = total24hs_PM_10;
weather["PMS 5003"]["Average of 24hs PM 10"] = media24hs_PM_10;
weather["PMS 5003"]["PM 10 AQI"] = AQI_PM_10;
weather["PMS 5003"]["Air Quality PM 10"] = air_quality_PM_10;
weather["PMS 5003"]["Air Quality Comparison"] = range_index;
weather["Rain Bucket"]["Rain Rate"] = rainrate;
weather["Rain Bucket"]["Rain Total"] = raintotal;
weather["Wind"]["Speed"]= wind_speed_kmh;
weather["Wind"]["Direction Cardinal"]= wind_direction_cardinal;
weather["Wind"]["Direction Degrees"]= wind_direction_degrees;
weather["Wind"]["Chill"]= Wind_Chill;
weather["Circuit Temperature"]["Circuit"]= temperature;
weather["Circuit Temperature"]["Battery 1"] = batt_temp1;
weather["Circuit Temperature"]["Battery 2"] = batt_temp2;
Serial.print(F("Sending: "));
serializeJson(weather, Serial);
Serial.println();
WiFiClient client;
HTTPClient http;
serializeJson(weather, buffer);
Serial.print("[HTTP] begin...\n");
// configure traged server and url
http.begin(client, "http://"SERVER_IP"/rest/post_data"); //HTTP
http.addHeader("Content-Type", "application/json");
Serial.print("[HTTP] POST...\n");
// start connection and send HTTP header and body
int httpCode = http.POST(buffer);
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] POST... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK) {
const String& payload = http.getString();
Serial.print("Received Payload: ");
Serial.println(payload);
Serial.println();
}
} else {
Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(500);
}
at the other side, on server:
.
.
.
const char* ssid = STASSID;
const char* password = STAPSK;
void handleRoot() {
server.send(200, "text/plain", "Hello from ESP8266!");
}
void handleNotFound() {
server.send(404, "text/plain", "File not found...");
}
void setup(void) {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("ESP8266 - MDNS responder started");
}
server.on("/", handleRoot);
server.on("/rest/post_data", []() {
if (server.hasArg("plain")== false){ //Check if body received
server.send(400, "text/plain", "Bad request: body not received");
} else { // we received a body, hopefully our JSON data
String message = server.arg("plain");
message += "\n";
Serial.print("Server - Json Received: ");
Serial.println(message);
// Allocate the JSON document
const size_t capacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2) + 5*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 2*JSON_OBJECT_SIZE(10) + 610;
DynamicJsonDocument doc(capacity);
// Parse JSON object
DeserializationError error = deserializeJson(doc, message);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
JsonObject Date = doc["Date"];
int Date_Day = Date["Day"]; // 165
int Date_Month = Date["Month"]; // 165
int Date_Year = Date["Year"]; // 2165
const char* Date_Weekday = Date["Weekday"]; // "Monday"
JsonObject Time = doc["Time"];
int Time_Hour = Time["Hour"]; // 165
int Time_Minute = Time["Minute"]; // 165
int Time_Second = Time["Second"]; // 85
int WiFi_WiFi_Signal_Strenght = doc["WiFi"]["WiFi Signal Strenght"];
JsonObject BME280 = doc["BME280"];
int BME280_Temperature = BME280["Temperature"]; // 0
int BME280_Humidity = BME280["Humidity"]; // 0
int BME280_DewPoint = BME280["DewPoint"]; // 0
int BME280_Pressure = BME280["Pressure"]; // 0
int BME280_Pressure_Equivalent = BME280["Pressure Equivalent"]; // 0
JsonObject VEML_6075 = doc["VEML-6075"];
int VEML_6075_UVA = VEML_6075["UVA"]; // 0
int VEML_6075_UVB = VEML_6075["UVB"]; // 0
int VEML_6075_UV_Index = VEML_6075["UV Index"]; // 0
JsonObject PMS_5003 = doc["PMS 5003"];
JsonObject PMS_5003_Last_Read_Sample = PMS_5003["Last Read Sample"];
int PMS_5003_Last_Read_Sample_PM_1_0 = PMS_5003_Last_Read_Sample["PM 1.0"]; // 0
int PMS_5003_Last_Read_Sample_PM_2_5 = PMS_5003_Last_Read_Sample["PM 2.5"]; // 0
int PMS_5003_Last_Read_Sample_PM_10 = PMS_5003_Last_Read_Sample["PM 10"]; // 0
int PMS_5003_Total_of_24hs_PM_2_5 = PMS_5003["Total of 24hs PM 2.5"]; // 0
int PMS_5003_Average_of_24hs_PM_2_5 = PMS_5003["Average of 24hs PM 2.5"]; // 0
int PMS_5003_PM_2_5_AQI = PMS_5003["PM 2.5 AQI"]; // 0
const char* PMS_5003_Air_Quality_PM_2_5 = PMS_5003["Air Quality PM 2.5"]; // ""
int PMS_5003_Total_of_24hs_PM_10 = PMS_5003["Total of 24hs PM 10"]; // 0
int PMS_5003_Average_of_24hs_PM_10 = PMS_5003["Average of 24hs PM 10"]; // 0
int PMS_5003_PM_10_AQI = PMS_5003["PM 10 AQI"]; // 0
const char* PMS_5003_Air_Quality_PM_10 = PMS_5003["Air Quality PM 10"]; // ""
const char* PMS_5003_Air_Quality_Comparison = PMS_5003["Air Quality Comparison"]; // ""
int Rain_Bucket_Rain_Rate = doc["Rain Bucket"]["Rain Rate"]; // 0
int Rain_Bucket_Rain_Total = doc["Rain Bucket"]["Rain Total"]; // 0
JsonObject Wind = doc["Wind"];
int Wind_Speed = Wind["Speed"]; // 0
const char* Wind_Direction_Cardinal = Wind["Direction Cardinal"]; // ""
int Wind_Direction_Degrees = Wind["Direction Degrees"]; // 0
JsonObject Circuit_Temperature = doc["Circuit Temperature"];
int Circuit_Temperature_Circuit = Circuit_Temperature["Circuit"]; // 0
int Circuit_Temperature_Battery_1 = Circuit_Temperature["Battery 1"]; // 0
int Circuit_Temperature_Battery_2 = Circuit_Temperature["Battery 2"]; // 0
server.send(200, "text/plain", "Successfully Received...");
}
});
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
MDNS.update();
}
what could be wrong?
Thanks,
lcfelippe.
Hi Icefelippe,
I don't know why you need to reboot; maybe you should try with a simpler example. Anyway, I don't think this issue is related to ArduinoJson.
Best regards, Benoit
Hi @bblanchon,
I solved it cleaning the buffer variable every time before serialize the JSON on client.
void loop(){
buffer = "";
.
.
.
}
Regards,
lcfelippe.
Hi @lcfelippe,
Indeed, serializeJson()
appends to String
, just as it would do with a Stream
.
You didn't show the declaration of buffer
, so I didn't realize you were (re-)using a String
.
Best regards, Benoit
Hi bblanchon,
how can i send a serialized json data to a server(esp8266)?. Can you help me with it?
Thanks for the good job on ArduinoJson.
Regards,
lcfelippe.