ESP32 Asynch Web Server POST method not working - post

I'm having trouble getting the POST method to work with the ESP32 & the Async Web Server. To be precise, the POST route is recognised but processing of the body fails.
The ESP32 is a WROOM-32. The POST example is adapted from ESP32 Arduino async HTTP server: Serving HTML
The web server and indeed the ESP32 appears to work in every other way I have tried. Although my example below doesn't show it, the GET method works just fine. The problem arises when I try to process the body of the POST request. I have put a comment in the code "Code here is NOT execute" to show what is not working. The simple form "/testform.html" is displayed, but when submitted, the header part of the POST handler shows that the content type is "application/x-www-form-urlencoded", but nothing is returned to the Chrome browser and the print statements intended to show the body of the POST do not execute.
The ESP32 code is as follows (I'm using the Arduino IDE):
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include "SPIFFS.h"
const char* ssid = "xxxxxx"; // Actual SSID & Pw removed
const char* password = "xxxxxx";
AsyncWebServer server(80);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Initialize SPIFFS
if(!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
Serial.println(WiFi.localIP());
server.on("/testform.html", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(SPIFFS, "/testform.html", String(), false);
});
server.on(
"/my-handling-form-page",
HTTP_POST,
[](AsyncWebServerRequest * request) {
// The following print statements work + removing them makes no difference
// This is displayed on monitor "Content type::application/x-www-form-urlencoded"
Serial.print("Content type::");
Serial.println(request->contentType());
}, // Route handling function
NULL,
[](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) {
// *** Code here is NOT executed ***
for (size_t i = 0; i < len; i++) {
Serial.write(data[i]);
}
Serial.println();
request->send(200);
});
// Start server
server.begin();
}
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "My not found ***** ");
}
void loop()`{
}
The "testform.htm" web page, is pretty simple and displays as expected when requested by the browser
<!DOCTYPE html>
<html>
<head>
<b>Test Form</b>
</head>
<body>
<form action="/my-handling-form-page" method="post">
<ul>
<li>
<label for="name">Name:</label>
<input type="text" id="name" name="user_name">
</li>
</ul>
<li class="button">
<button type="submit">Send your message</button>
</li>
</form>
</body>
</html>
I hope someone can either find the obvious boo-boo or give me a clue to what I might try next.

Adding this here in case it is useful for someone even though the question is old.
It seems that the form of server.on() that you are using doesn't give you access to the POST body. In my testing, I can't see any parameters when using the form you are using.
However: there is a 5-argument version that allows you to attach a body handler. Inside that function, you can read the body byte-for-byte and parse it. Here is an example that uses the ArduinoJSON library.
// in your webserver setup function
server.on("/mypage",HTTP_POST, handleMyPage, nullptr, parseMyPageBody);
// callback definition
void parseMyPageBody(AsyncWebServerRequest* req, uint8_t* data, size_t len, size_t index, size_t total) {
DynamicJsonDocument bodyJSON(1024);
deserializeJson(bodyJSON, data, len);
String tag1 = bodyJSON["tag1"];
String tag2 = bodyJSON["tag2"];
// rest of code
}

The below code works..
server.on(
"/post",
HTTP_POST,
[](AsyncWebServerRequest * request){
// The following print statements work + removing them makes no difference
// This is displayed on monitor "Content type::application/x-www-form-urlencoded"
Serial.print("Content type::");
Serial.println(request->contentType());
Serial.println("OFF hit.");
String message;
int params = request->params();
Serial.printf("%d params sent in\n", params);
for (int i = 0; i < params; i++)
{
AsyncWebParameter *p = request->getParam(i);
if (p->isFile())
{
Serial.printf("_FILE[%s]: %s, size: %u", p->name().c_str(), p->value().c_str(), p->size());
}
else if (p->isPost())
{
Serial.printf("%s: %s \n", p->name().c_str(), p->value().c_str());
}
else
{
Serial.printf("_GET[%s]: %s", p->name().c_str(), p->value().c_str());
}
}
});

Related

ESP NOW failing using WIFI_AP_STA and WiFi.begin but working without the WiFi.begin

I am using code derived from Rui Santos https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
I am using ESP NOW to send readings from an ESP32 sender to an ESP32 receiver then using the ESP32 receiver to send an html message to a ESP32 web server. Per Rui's instructions I need to start WiFi with WIFI_AP_STA to allow both wifi connection methods.
The sender and receiver code is below.
If I run the code as is, i.e. the receiver setup as WIFI_AP_STA but with the WiFi.begin line commented out, I get a sender status of:
Send success, and a receive status of:Receive status. SO there is no problem sending an ESP NOW message from the sender to the receiver (also works with WIFI_STA).
If I use WIFI_AP_STA and uncomment the line in the receiver "WiFi.begin(SSIS, PASSWORD)" so that I can send a message to the ESP32 web server, I get a send status of:Send fail, and a receive status of:Receive status with failed send. The send fails but the receive is still successful. Same fail if I use WIFI_AP. It seems that in WIFI_AP_STA mode with a WiFi.begin, the receiver sends an incorrect status back to the sender.
In summary, on the receiver, using wifi mode WIFI_AP_STA without a WiFi.begin, works for sending an ESP NOW message from sender to receiver, as it should.
Using wifi mode WIFI_AP_STA and WiFi.begin on the receiver, the sender fails when sending an ESP NOW message. When I implement the web code the web html message send works. However the issue can be reproduced using the simplified code below.
Using WiFi#2.0.0.
I've run out of ideas, is anyone able to point me at further investigation areas?
My sender code is:
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
// Rui Santos https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
uint8_t broadcastAddress[] = {0x24, 0x6F, 0x28, 0xAA, 0x84, 0x10};
typedef struct struct_message
{
char ESP32NowText[33];
} struct_message;
struct_message ESP32NowMessage;
//
String text = "AAA000010000200003000040000500006";
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK)
{
Serial.println("Failed to add peer");
return;
}
}
void loop()
{
strncpy(ESP32NowMessage.ESP32NowText, text.c_str(), text.length());
Serial.println("Msg to send:" + String(ESP32NowMessage.ESP32NowText));
Serial.println("Snd Len:" + String(sizeof(ESP32NowMessage)));
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&ESP32NowMessage, sizeof(ESP32NowMessage));
if (result == ESP_OK)
{
Serial.println("Sent with success");
}
else
{
Serial.println("Error sending the data");
}
delay(2000);
}
My receiver code is:
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
// Rui Santos https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
typedef struct struct_message
{
char ESP32NowValues[33];
} struct_message;
struct_message ESP32NowMessage;
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len)
{
memcpy(&ESP32NowMessage, incomingData, sizeof(ESP32NowMessage));
Serial.println("Bytes received: " + String(len));
Serial.println("Values:" + String(ESP32NowMessage.ESP32NowValues));
Serial.println("---------------------------------------");
}
const char WiFiSSID[] = "SSID";
const char WiFiPassword[] = "PASSWORD";
//
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_AP_STA);
// WiFi.begin(WiFiSSID, WiFiPassword);
// Init ESP-NOW
if (esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop()
{
}

ESP8266 WIFI single relay ESP-12F Dev board

I am beginner. I am using ESP8266 WIFI single relay ESP-12F Dev board to send some data over MQTT with PubSub client, it used to work well but after sometime(1-2 days) it does not receive message through MQTT. When I reset the board, it get starts working. I do not where the issue is and where is it freezing.
I am storing MQTT credentials in EEPROM also.
Here's my code
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <PubSubClient.h>
#include <WiFiManager.h>
#include <EEPROM.h>
WiFiClient espClient;
PubSubClient client(espClient);
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<body>
<h3> HTML Form ESP8266</h3>
<form action="/action_page">
Topic name:<br>
<input type="text" name="PublishTopic" value="">
<br>
Broker name:<br>
<input type="text" name="Mqtt_Broker" value="">
<br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
)=====";
//SSID and Password of your WiFi router
const char* ssid = "Cherry"; //Daalchini#2.4Ghz
const char* password = "ravan#123"; //G_2425G_A
ESP8266WebServer server(80); //Server on port 80
//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
String s = MAIN_page; //Read HTML contents
server.send(200, "text/html", s); //Send web page
}
//===============================================================
// This routine is executed when you press submit
//===============================================================
void handleForm() {
String PublishTopic = server.arg("PublishTopic");
String Mqtt_Broker = server.arg("Mqtt_Broker");
const char* topic = PublishTopic.c_str(); //strstr( PublishTopic.c_str(), "]" );
const char* mqtt_server = Mqtt_Broker.c_str();
Serial.print("topic:");
Serial.println(topic);
Serial.print("PublishTopic:");
Serial.println(PublishTopic);
Serial.print("mqtt_server:");
Serial.println(mqtt_server);
Serial.print("MQTT Broker:");
Serial.println(Mqtt_Broker);
if(mqtt_server)
{
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
reconnect(topic);
if(!client.connected())
{
reconnect(topic);
Serial.print("disconnected");
}
}
String s = "<a href='/'> Go Back </a>";
server.send(200, "text/html", s); //Send web page
// Writing
int str1AddrOffset = writeStringToEEPROM(0,topic);
int str2AddrOffset = writeStringToEEPROM(str1AddrOffset,mqtt_server);
}
//==============================================================
// SETUP
//==============================================================
//===========================================
void callback(char* topic, byte* payload, unsigned int length)
{
Serial.print("Message arrived : ");
Serial.print(topic);
Serial.print(" : ");
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
}
//===========================================
void reconnect(const char* topic)
{
while(!client.connected()){
Serial.println("Attempting MQTT connection");
if(client.connect(""))
{
Serial.println("Connected");
//client.publish("justinmqtt/house/TMP","Connected!");
client.subscribe(topic);
Serial.print("subscribed!");
}
else
{
Serial.print("Failed, rc = ");
Serial.print(client.state());
Serial.println("Waiting for 5 seconds to try again");
delay(5000);
}
}
}
void setup(void){
Serial.begin(9600);
EEPROM.begin(512);
WiFi.begin(ssid, password); //Connect to your WiFi router
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//If connection successful show IP address in serial monitor
Serial.println("");
Serial.print("Connected to ");
Serial.println("WiFi");
String newStr1;
String newStr2;
int readstr = readingData(0, &newStr1);
int readstr1 = readingData(readstr, &newStr2);
const char* top = newStr1.c_str(); //strstr( PublishTopic.c_str(), "]" );
const char* servermqtt = newStr2.c_str();
Serial.println("top");
Serial.println(top);
Serial.println("servermqtt");
Serial.println(servermqtt);
if(servermqtt)
{
Serial.print("entering in a loop: ");
client.setServer(servermqtt, 1883);
client.setCallback(callback);
reconnect(top);
if(!client.connected())
{
reconnect(top);
Serial.print("disconnected");
}
}
else{
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
server.on("/", handleRoot); //Which routine to handle at root location
server.on("/action_page", handleForm); //form action is handled here
server.begin(); //Start server
Serial.println("HTTP server started");
}
// Serial.print("IP address: ");
// Serial.println(WiFi.localIP()); //IP address assigned to your ESP
//
// server.on("/", handleRoot); //Which routine to handle at root location
// server.on("/action_page", handleForm); //form action is handled here
//
// server.begin(); //Start server
// Serial.println("HTTP server started");
}
//==============================================================
// WRITE EEPROM
//==============================================================
int writeStringToEEPROM(int addrOffset, const String &strToWrite)
{
Serial.println("Writing Data ");
byte len = strToWrite.length();
Serial.println(len);
EEPROM.write(addrOffset, len);
for (int i = 0; i < len; i++)
{
EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
}
EEPROM.commit();
return addrOffset + 1 + len;
}
//==============================================================
// READ EEPROM
//==============================================================
int readingData(int addrOffset, String *strToRead)
{
Serial.println("Reading Data");
int newStrLen = EEPROM.read(addrOffset);
char data[newStrLen + 1];
for (int i = 0; i< newStrLen; i++) {
data[i] = EEPROM.read(addrOffset + 1 + i);
}
data[newStrLen] = '\0';
Serial.println(data);
*strToRead = String(data);
return addrOffset + 1 + newStrLen;
}
//==============================================================
// LOOP
//==============================================================
void loop(void){
server.handleClient(); //Handle client requests
yield();
delay(50);
client.loop();
}

ESP8266 Subscribe to AWS IOT topic

Hi I need to create a lambda function which will access the AWS thing and publish MQTT message, I'd like to get the published message on the ESP8266 which was connected to the thing as well, and controlled turn on/off the LED on ESP8266. So far I have uploaded the private.der, cert.der and ca.der to the ESP8266 absolutely, but it couldn't subscribed AWS IOT, please point me in the right tips then please share.
Code:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ArduinoJson.h>
#define OUT_TOPIC "$aws/things/devices/shadow/update"
#define IN_TOPIC "$aws/things/devices/shadow/update/delta"
const char* ssid = "sid";
const char* password = "password";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
const char* AWS_endpoint = "endpoint.amazonaws.com";//MQTT broker ip
const char* json = "{\"state\":{\"reported\":{\"led\":\"off\"}}}";
StaticJsonDocument<1024> doc;
WiFiClientSecure espClient;
PubSubClient mqttClient(espClient);//set MQTT port number to 8883 as per standard
PubSubClient client(AWS_endpoint, 8883, espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup_wifi() {
delay(10);// We start by connecting to a WiFi network
espClient.setBufferSizes(512, 512);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
timeClient.begin();
while(!timeClient.update()){
timeClient.forceUpdate();
}
espClient.setX509Time(timeClient.getEpochTime());
int qos = 0;//Maximum size of data that can be communicated
Serial.println(MQTT_MAX_PACKET_SIZE);
if(mqttClient.subscribe(IN_TOPIC, qos)){
Serial.println("Subscribed.");
Serial.println("Success!!");
}
deserializeJson(doc, json);
JsonObject obj = doc.as<JsonObject>();
if(mqttClient.publish(OUT_TOPIC, json)){
Serial.println("Published!!");
}
}
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
setup_wifi();
delay(1000);
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
Serial.print("Heap: "); Serial.println(ESP.getFreeHeap());
//replace cert.crt eith your uploaded file name
File cert = SPIFFS.open("/cert.der", "r");
if (!cert) {
Serial.println("Failed to open cert file");
}
else
Serial.println("Success to open cert file");
delay(1000);
if (espClient.loadCertificate(cert))
Serial.println("cert loaded");
else
Serial.println("cert not loaded");
// Load private key file
File private_key = SPIFFS.open("/private.der", "r");//replace private eith your uploaded file name
if (!private_key) {
Serial.println("Failed to open private cert file");
}
else
Serial.println("Success to open private cert file");
delay(1000);
if (espClient.loadPrivateKey(private_key))
Serial.println("private key loaded");
else
Serial.println("private key not loaded");
// Load CA file
File ca = SPIFFS.open("/ca.der", "r");
//replace ca eith your uploaded file name
if (!ca) {
Serial.println("Failed to open ca ");
}
else
Serial.println("Success to open ca");
delay(1000);
if(espClient.loadCACert(ca))
Serial.println("ca loaded");
else
Serial.println("ca failed");
Serial.print("Heap: ");
Serial.println(ESP.getFreeHeap());
}
void callback (char* topic, byte* payload, unsigned int length) {
Serial.println("Received. topic=");
Serial.println(topic);
char subsc[length];
for(int i=0; i<length; i++){
subsc [i]=(char)payload[i];
subsc [length]='\0';
Serial.print(subsc);
}
Serial.print("\n");
digitalWrite(LED_BUILTIN, HIGH);
}
void mqttLoop() {
mqttClient.loop();
delay(100);
//digitalWrite(LED_pin, LOW);
digitalWrite(LED_BUILTIN, LOW);
Serial.print(".");
}
void loop() {
It looks like you're using the older forms of WiFiClientSecure certificate handling. I'll assume that's working OK and you're able to establish an SSL connection.
Your IN_TOPIC needs to be updated slightly to: $aws/things/<name-of-your-thing>/shadow/update/accepted (where hopefully you know what <name-of-your-thing> is). You can get this from the thing shadow on your AWS console.
Similarly AWS_endpoint needs updating: it should be of the form <random-stuff-specific-to-you>.iot.<region>.amazonaws.com. You can also find it from the same place as the MQTT topics.
You only want one instance of PubSubClient. I'll assume you delete client and keep mqttClient. You'll need to update the instantiation to include the AWS endpoint and port as you have done for client.
Before calling mqttClient.subscribe(...) you need to register the callback:
mqttClient.setCallback(::callback);
then connect to AWS:
mqttClient.connect("some-unique-name");
Finally, you need to edit PubSubClient.h (look for it in Arduino/libraries/PubSubClient/src) to update MQTT_MAX_PACKET_SIZE. The default is 128 and I've found that too small with AWS's messages. I've made mine 1024:
#define MQTT_MAX_PACKET_SIZE 1024
and that appears ample.
Once that compiles and runs you'll start seeing callback(...) called with the topics you've subscribed to and you can implement the function to do whatever you need.
The PubSubClient doesn't do much error reporting to help diagnose what's going on. I'm currently refactoring it a bit and including more diagnostic information and will eventually issue a pull request. Let me know if you'd like my hacked version before I get that far.

How to connect into Action Cable websocket from Arduino?

I built an app in Python Flask which controls the LED light on an Arduino through broadcasting the color selected in a form to all members of the websocket channel. I am now rebuilding in Rails and trying to determine how my Arduino can specify which channel it would like to join. I've already begun a connection to the WebSocket and seem to be getting the following back from Rails: [WSc] Received text: {"type":"ping","message":1544679171}.
Now I just need to determine how I can send in a request to specifically stream from the ArduinoChannel, but I'm not sure how to go about it. I've tried adding parameters to my webSocket.begin, but that doesn't seem to have any affect.
Below is my Arduino code for reference:
#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
// Initialize pins
int redpin = D0;
int greenpin = D2;
int bluepin = D4;
//// Connecting to the internet
const char* ssid = "**************";
const char* password = "******";
// Setting up the websocket client
WebSocketsClient webSocket;
// Set up the WiFi client;
WiFiClient client;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(redpin, OUTPUT);
pinMode(bluepin, OUTPUT);
pinMode(greenpin, OUTPUT);
delay(10);
WiFi.begin(ssid, password);
while(WiFi.status()!= WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.print("IP Address: ");
Serial.print(WiFi.localIP() + "\n");
Serial.print(WiFi.macAddress() + "\n");
// Initializing the WS2812B communication
setRgb(255,80,90);
// Initializing the websocket connection
webSocket.begin("192.168.1.93",3000, "/cable" );
// webSocket.sendTXT('{"command":"subscribe","identifier":"{\"channel\":\"ArduinoChannel\"}"', 0);
webSocket.onEvent(webSocketEvent);
webSocket.setReconnectInterval(5);
}
void loop() {
// put your main code here, to run repeatedly:
webSocket.loop();
}
void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) {
switch(type) {
Serial.write(type);
case WStype_DISCONNECTED:
Serial.printf("[WSc] Disconnected!\n");
break;
case WStype_CONNECTED:
Serial.printf("[WSc] Connected to url: %s\n", payload);
break;
case WStype_TEXT:
Serial.printf("[WSc] Received text: %s\n", payload);
DynamicJsonBuffer jBuffer;
JsonObject &root = jBuffer.parseObject(payload);
setRgb(root["r"],root["g"],root["b"]);
break;
}
}
void setRgb(uint8_t r, uint8_t g, uint8_t b) {
analogWrite(redpin, r);
analogWrite(bluepin, b);
analogWrite(greenpin, g);
delay(10);
}
TL;DR:
how I can send in a request to specifically stream from the ArduinoChannel
To receive streams from ArduinoChannel, you'll need to "subscribe" by sending through Websocket connection the following the String data from Arduino-client:
"{\"command\":\"subscribe\",\"identifier\":\"{\\\"channel\\\":\\\"ArduinoChannel\\\"}\"}"
... which is almost the same as your commented out sendTXT code, but that probably you were just incorrectly "escaping" the double quotes.
References:
I traced from the JS-client version of ActionCable here
App.cable.subscriptions.create('ArduinoChannel')
Subscriptions.prototype.create = function create(channelName, mixin) {
var channel = channelName;
var params = (typeof channel === "undefined" ? "undefined" : _typeof(channel)) === "object" ? channel : {
channel: channel
};
// params = { channel: "ArduinoChannel" }
var subscription = new Subscription(this.consumer, params, mixin);
return this.add(subscription);
};
function Subscription(consumer) {
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var mixin = arguments[2];
classCallCheck(this, Subscription);
this.consumer = consumer;
this.identifier = JSON.stringify(params);
extend(this, mixin);
}
Subscriptions.prototype.add = function add(subscription) {
this.subscriptions.push(subscription);
this.consumer.ensureActiveConnection();
this.notify(subscription, "initialized");
this.sendCommand(subscription, "subscribe");
return subscription;
};
Subscriptions.prototype.sendCommand = function sendCommand(subscription, command) {
var identifier = subscription.identifier;
// command = "subscribe"; identifier = JSON.stringify(params) = '{"channel":"ArduinoChannel"}';
return this.consumer.send({
command: command,
identifier: identifier
});
};
Consumer.prototype.send = function send(data) {
// data = { command: 'subscribe', identifier: '{"channel":"ArduinoChannel"}' }
return this.connection.send(data);
};
Connection.prototype.send = function send(data) {
if (this.isOpen()) {
// JSON.stringify(data) = '{"command":"subscribe","identifier":"{\"channel\":\"ArduinoChannel\"}"}'
this.webSocket.send(JSON.stringify(data));
return true;
} else {
return false;
}
};

How do I use method POST in Arduino IDE Ethernet Library, using Ruby on Rails API as post method?

friends.
I want to post data to web server from my Arduino setup, and I want to post it via Post Method to server side, running Ruby on Rails.
Already test my backend using postman, and it works like a charm.
Now I have a problem when I want to post it from arduino setup, it doesn't work. Server side never get the connection from arduino.
For Arduino setup I use ethernet.h Library.
//------------------------------------------
// Park Sensor Prototype
// Only insert if there is car parked
//------------------------------------------
#include <Ethernet.h>
//servername
char server[] = "https://spark-backend.herokuapp.com";
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetClient client;
String data;
bool flagstatus = false;
void setup() {
Serial.begin(9600);
// Connect to Ethernet
Ethernet.begin(mac);
}
void loop() {
int sensorvalue = analogRead(A0); // LightValue, read from sensor pin A0
// String templ= "sensorvalue=";
// data = templ + String(sensorvalue);
String parkspot_id= "{parkspot_id:""'""SP001""'"",";
String sensor_in="sensor_in:""'""";
String user_id=",user_id:""'""U001""'""}";
String valueinput = String(sensorvalue);
//data = parkspot_id + sensor_in + "'"valueinput"'"+","+user_id;
data = parkspot_id +sensor_in+valueinput+"'"+user_id;
/*
{ park_spot_id: “SP001” , sensor_in: “100”, user_id:”U001”}
*/
//there is a car parked
if(sensorvalue >=1000){
if(flagstatus == false){
Serial.println("Insert to DB, there is a car just parked");
if (client.connect(server, 80)){
Serial.println("Connected to server");
Serial.println(data);
client.println("POST /api/v1/parks HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(data.length());
client.println();
client.print(data);
client.stop();
}
flagstatus = true;
} else {
Serial.println("There is still a car parked");
}
} else{
Serial.println("There is no car parked");
flagstatus = false;
}
delay(10000); // delay ten seconds
}
I really need your advice :D Thank you in advance. Please correct me or teach me how to solve it :)
i think you POST json like data with wrong header Content-Type: application/x-www-form-urlencoded, change it to application/json please.

Resources