Posting data from esp8266 to a webapi - asp.net-web-api

I want to send data from my esp8266 to a webapi but it fails.
I tried this code to send my data like sensor status but it fails and returns error 400. I searched a lot about this problem and I tried so many things but it didn't work.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
const char *ssid = "VRU";
const char *password = "";
const char *host = "192.168.174.71";
WiFiClient wifiClient;
void setup() {
delay(1000);
Serial.begin(115200);
WiFi.mode(WIFI_OFF);
delay(1000);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
Serial.print("Connecting");
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());
}
void loop() {
HTTPClient http;
http.begin(wifiClient,"http://192.168.174.71:100/api/StatusReport/AddStatus");
http.addHeader("Content-Type", "application/json");
int httpCode = http.POST("{\"status\":\"1\"}");
String payload = http.getString();
Serial.println(httpCode);
Serial.println(payload);
http.end();
delay(5000);
}
Here is my code. It connects to the wifi without any problem and when it wants to post the data it returns an error.
400
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-862f434a8be85865c871ea45b89544d1-cea4232cafaa5cc1-00","errors":{"status":["The status field is required."]}}
And it's the error.
The api receives the data when I do it by myself but the esp can't send the data.
What should I do to prevent this error from happening. Is it from the api that can't receive data or from the esp?

Related

WebSocketServer on ESP32 DevkitC V4 Issue

I'm developing a simple mobile robot controlled by a custom web application hosted on ESP32. The communication protocol that is used is WebSocket. I had a code that was working but after some break, I can't make it run properly again... most likely I changed something accidentally or I don't understand some code parts. The logs in SerialPort suggest that the program connects to the WiFi, it gets data (HTML files) from Flash memory and the server is started under some particular IP. However, when I try to access the server IP nothing is given in response. I pasted my .ino code down below, I can also add HTML and .js files if needed. The data folder is ofc uploaded to the flash memory. For now I just want to host that page on a server and access it, the code is not supposed to do anything else for now. I'm going crazy because of that issue. Does anyone see some mistake or misconception?
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "SPIFFS.h"
#include <Arduino_JSON.h>
// Network credentials
const char *ssid = "mySSID";
const char *password = "myCredentials";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Create a WebSocket object
AsyncWebSocket ws("/ws");
// Placeholder for messages from the clients
String message = "";
void initFS()
{
if (!SPIFFS.begin())
{
Serial.println("An error has occurred while mounting SPIFFS");
}
else
{
Serial.println("SPIFFS mounted successfully");
}
}
// Initialise WiFi
void initWiFi()
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len)
{
AwsFrameInfo *info = (AwsFrameInfo *)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT)
{
data[len] = 0;
message = (char *)data;
}
}
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len)
{
switch (type)
{
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
break;
case WS_EVT_DATA:
handleWebSocketMessage(arg, data, len);
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
}
}
void initWebSocket()
{
Serial.println("I'm Inside!");
ws.onEvent(onEvent);
server.addHandler(&ws);
}
void setup()
{
Serial.begin(115200);
Serial.println("Initialising SPIFFS");
initFS();
Serial.println("Initialising WiFi");
initWiFi();
Serial.println("Initialising WebSocket");
initWebSocket();
// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(SPIFFS, "/index.html", "text/html"); });
server.serveStatic("/", SPIFFS, "/");
// Start server
server.begin();
Serial.println("Starting Server");
}
void loop()
{
ws.cleanupClients();
}
Update:
I created a different, very simple sketch just to have a look if it might work and it doesn't. It connects to the WiFi according to the logs but I'm getting timed out when I try to access the server IP address Down below is the code that I used for the second sketch:
#include <WiFi.h>
#include <WebServer.h>
//SSID and Password to the local WiFi
const char* ssid = "ssid";
const char* password = "password";
WebServer server(80);
String webpage = "<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <title>Document</title></head><body> <h1> Test! </h1></body></html>";
//Function to initialise the connection with local WiFi
void InitWiFi()
{
WiFi.begin(ssid, password);
Serial.println("Trying to connect to the WiFi with SSID: " + String(ssid) + "..");
while(WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Connected to the WiFi with the IP address: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
InitWiFi();
//Initialising WebServer
server.on("/", []() {
server.send(200, "text\html", webpage);
});
delay(1000);
server.begin();
Serial.println("Server started");
}
void loop() {
server.handleClient();
}

ESP8266 not connecting to websocket server

I have created and deployed a websocket to the heroku. I am able to use the websocket on postman but I can't connect it with my node mcu. I could connect the node mcu to the wifi but not with the websocket.
I am not sure about the port number which should be used for begin() method for websocketsclient object.
Below is my code to connect with my websocket:
#include "ESP8266WiFi.h"
#include "WebSocketsClient.h"
// WiFi parameters to be configured
const char* ssid = "<wifi_ssid>"; // Write here your router's username
const char* password = "<password>"; // Write here your router's passward
int LED_STATUS = 0;
const char* host = "<project_name>.herokuapp.com";
const uint16_t port = 3000;
const char* url = "/";
WebSocketsClient webSocketsClient = WebSocketsClient();
void handleMessage(char * message){
Serial.println("message...");
Serial.println(message);
}
void webSocketCallback(WStype_t type, uint8_t * payload, size_t length){
toggleLED();
switch(type){
case WStype_DISCONNECTED:
offLED();
break;
case WStype_TEXT:
onLED();
handleMessage((char*) payload);
break;
case WStype_CONNECTED:
default:
onLED();
break;
}
}
void toggleLED(){
LED_STATUS = (LED_STATUS + 1)%2;
digitalWrite(LED_BUILTIN, LED_STATUS);
}
void offLED(){
LED_STATUS = 1;
digitalWrite(LED_BUILTIN, LED_STATUS);
}
void onLED(){
LED_STATUS = 0;
digitalWrite(LED_BUILTIN, LED_STATUS);
}
void setup(void)
{
Serial.begin(9600);
// Connect to WiFi
WiFi.begin(ssid, password);
//setting the led pin
pinMode(LED_BUILTIN, OUTPUT);
// while wifi not connected yet, print '.'
// then after it connected, get out of the loop
while (WiFi.status() != WL_CONNECTED) {
toggleLED();
delay(500);
Serial.print(".");
}
//WiFi connected, IP address
Serial.println("");
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
offLED();
//websocket connection
webSocketsClient.begin(host, port, url);
webSocketsClient.onEvent(webSocketCallback);
webSocketsClient.setReconnectInterval(5000);
}
void loop() {
// Nothing
webSocketsClient.loop();
}
Solutions(few mistakes in the code):
Since my websocket supports secured connection : wss, so instead of begin() need to use beginSSL()
since wss is used, port number for secured connections is 443

ESP8266 Returning code 400 on POST request in Django webapp

I deployed my django webapp to the internet but I can't POST request a data because it's returning
HTTP CODE 400,
const char* serverName = "https://example.com/api/v1/post_sample"; = returns 400 code.
but when I do: const char* serverName = "http://localhost:8000/api/v1/post_sample"; it works and return 201 code.
It didn't put any restrictions or auth for now on the web application. I even did a POST request on Postman to the web application I deployed, it also works.
Please help. Thanks!
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const char* serverName = "https://example.com/api/v1/post_sample";
unsigned long lastTime = 0;
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() {
if ((millis() - lastTime) > timerDelay) {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(serverName);
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.POST("{\"value\":\"1\"}");
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
You didn't establish a WiFiClient before trying to establish a http connection.
For POST request with ESP8266HTTPClient, you pass in the url when you establish http.begin(client, url) with an established client instance. See the example code. In your case, it should be:
if(WiFi.status()== WL_CONNECTED){
WiFiClient client;
HTTPClient http;
http.begin(client, serverName);
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.POST("{\"value\":\"1\"}");
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
If you url is an secure connection with https as you shown in your example url, then you will need to establish a secure client with a library like <WiFiClientSecureBearSSL.h>. See example.

esp8266 based project using xampp

I've tried uploading the below code into NodeMCU for sending data into MySQL using Xampp Webserver. I want to send values from sensors to the MySQL database through ESP8266. This is the code I have tried
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#define sensorPin1 analogRead(A0)
WiFiServer server(301);
const char *ssid = "internet";
const char *pass = "abcdefghi";
const char* host = "x.x.x.x";
byte mac[6];
WiFiClient client;
MySQL_Connection conn((Client *)&client);
char INSERT_SQL[] = "INSERT INTO test.tester(id,sensor) VALUES ('', %d)";
char query[128];
IPAddress server_addr(x,x,x,x); // MySQL server IP
char user[] = "root"; // MySQL user
char password[] = ""; // MySQL password
void setup() {
Serial.begin(9600);
delay(10);
Serial.println("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
WiFi.macAddress(mac);
Serial.print("MAC: ");
Serial.print(mac[5],HEX);
Serial.print(":");
Serial.print(mac[4],HEX);
Serial.print(":");
Serial.print(mac[3],HEX);
Serial.print(":");
Serial.print(mac[2],HEX);
Serial.print(":");
Serial.print(mac[1],HEX);
Serial.print(":");
Serial.println(mac[0],HEX);
Serial.println("");
Serial.print("Assigned IP: ");
Serial.print(WiFi.localIP());
Serial.println("");
Serial.println("Connecting to database");
while (conn.connect(server_addr, 3306, user, password) != true) {
delay(5);
Serial.print ( "." );
}
Serial.println("");
Serial.println("Connected to SQL Server!");
}
void loop() {
int sensor = sensorPin1;
delay(10000); //10 sec
sprintf(query, INSERT_SQL, sensor);
Serial.println("Data Recorded.");
Serial.println(query);
MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
cur_mem->execute(query);
delete cur_mem;
}
But when I execute this program, the chip is getting connected to WiFi but is is not getting connected to the database.
Any solutions please!?

nodeMCU connect refused with XMAPP localhost

My project is about using nodeMCU measure value from sensor DHT11 and sent value to database Mysql. I use xampp for server. I cannot sent value to database.
nodeMCU can read value and sent value.But HTTP GET is fail.And return connect refused. I think maybe have problems with port for listening.
this is my code
#include <Arduino.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include "DHT.h"
#define DHTPIN 2 // what digital pin the DHT22 is conected to
#define DHTTYPE DHT11 // there are multiple kinds of DHT sensors
DHT dht(DHTPIN, DHTTYPE);
ESP8266WiFiMulti WiFiMulti;
const char* ssid = "something";
const char* password = "something";
int EP =5;
void setup() {
Serial.begin(115200);
pinMode(EP, INPUT);
for (uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFiMulti.addAP(ssid, password); // ssid , password
randomSeed(50);
}
int timeSinceLastRead = 0;
void loop() {
if ((WiFiMulti.run() == WL_CONNECTED)) {
HTTPClient http;
float temp = dht.readTemperature();
float humi = dht.readHumidity();
long meas =TP_init();
Serial.println(WiFi.localIP());
//int temp = random(25,35);
String url = "localhost:8012/add2.php?temp="+String(temp)+"&humi="+String(humi)+"&meas=0";
Serial.println(url);
http.begin(url); //HTTP
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(3000);
}
long TP_init(){
delay(10);
long meas=pulseIn (EP, HIGH); //wait for the pin to get HIGH and returns measurement
return meas;
}
I changed Apache port from 80 to 8012
I use PHPMyadmin for store database . File php's name add2.php for insert value from sensor DHT11
enter image description here
This is result from serial port.
String url = "localhost should be replaced with String url = "<IP-address-of-your-webserver> as the webserver clearly isn't running on the ESP8266.

Resources